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: