A short and to-the-point post illustrating how a deadlock situation can be created in C++, together with a possible strategy for avoiding such a condition.
I’m am using the boost libraries to implement threads and mutexes, but it should be possible to the standard library implementations std::thread, std::mutex etc as well.
Scenario 1: Deadlock Condition
If thread A is executing and isn’t holding mutex lock 1 yet and thread B acquires mutex lock 2, neither of the threads can continue past the second lock acquisition:
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
boost::mutex mutex1, mutex2;
void ThreadA()
{
// Creates deadlock problem
mutex2.lock();
std::cout << "Thread A" << std::endl;
mutex1.lock();
mutex2.unlock();
mutex1.unlock();
}
void ThreadB()
{
// Creates deadlock problem
mutex1.lock();
std::cout << "Thread B" << std::endl;
mutex2.lock();
mutex1.unlock();
mutex2.unlock();
}
void ExecuteThreads()
{
boost::thread t1( ThreadA );
boost::thread t2( ThreadB );
t1.join();
t2.join();
std::cout << "Finished" << std::endl;
}
int main()
{
ExecuteThreads();
return 0;
}
When running this notice that the program hangs and is unable to proceed beyond the second mutex lock acquisition:
Scenario 2: Avoiding Deadlocks
The problem of deadlocks can avoided by maintaining consistency in the ordering of the locking and unlocking of mutexes:
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
boost::mutex mutex1, mutex2;
void ThreadA()
{
// Solves deadlock problem
mutex1.lock();
std::cout << "Thread A" << std::endl;
mutex2.lock();
mutex2.unlock();
mutex1.unlock();
}
void ThreadB()
{
// Solves deadlock problem
mutex1.lock();
std::cout << "Thread B" << std::endl;
mutex2.lock();
mutex1.unlock();
mutex2.unlock();
}
void ExecuteThreads()
{
boost::thread t1( ThreadA );
boost::thread t2( ThreadB );
t1.join();
t2.join();
std::cout << "Finished" << std::endl;
}
int main()
{
ExecuteThreads();
return 0;
}
Instead of waiting indefinitely threads A and B are able to complete:

