What is Deadlock in C++: Explanation and Example
deadlock is a situation where two or more threads are blocked forever because each thread is waiting for a resource held by another. This usually happens when threads lock multiple mutexes in different orders, causing a cycle of waiting that never resolves.How It Works
Imagine two people each holding a key to a different door, but each needs the other's key to open their own door. Neither can proceed because they are waiting for the other to give up their key. This is similar to a deadlock in C++ where threads wait for resources locked by each other.
In programming, threads use mutexes to protect shared data. If Thread A locks Mutex 1 and waits for Mutex 2, while Thread B locks Mutex 2 and waits for Mutex 1, both threads get stuck waiting forever. This cycle of waiting is called a deadlock.
Deadlocks stop the program from making progress and can cause it to freeze or crash. Detecting and avoiding deadlocks is important in multithreaded C++ programs.
Example
This example shows two threads causing a deadlock by locking two mutexes in opposite order.
#include <iostream> #include <thread> #include <mutex> std::mutex mutex1; std::mutex mutex2; void threadA() { std::lock_guard<std::mutex> lock1(mutex1); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::lock_guard<std::mutex> lock2(mutex2); std::cout << "Thread A acquired both mutexes\n"; } void threadB() { std::lock_guard<std::mutex> lock2(mutex2); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::lock_guard<std::mutex> lock1(mutex1); std::cout << "Thread B acquired both mutexes\n"; } int main() { std::thread t1(threadA); std::thread t2(threadB); t1.join(); t2.join(); return 0; }
When to Use
Deadlock is not something you want to use, but something to avoid. Understanding deadlocks helps you write safer multithreaded C++ programs.
Deadlocks often happen in programs that use multiple locks to protect shared resources, like databases, files, or shared data structures. If your program has multiple threads accessing shared data, you must design locking carefully to prevent deadlocks.
Use techniques like locking mutexes in a fixed order, using std::lock to lock multiple mutexes at once, or avoiding holding locks while waiting for other resources to prevent deadlocks.
Key Points
- Deadlock happens when threads wait forever for each other’s locked resources.
- It usually involves multiple mutexes locked in different orders.
- Deadlocks cause programs to freeze or stop responding.
- Prevent deadlocks by consistent locking order or using
std::lock. - Detecting deadlocks can be hard but designing carefully helps avoid them.