Deadlock
-
A thread is deadlocked when it cannot run
-
Often used to refer to "mutual deadlock"
- Two or more threads are waiting for each other
- Thread A waits for thread B to do something
- Thread B is waiting for A to do something
- Threads A and B are waiting for an event that can never happen
-
The classic example involves waiting for mutexes
Deadlock Example
#include <iostream>
#include <mutex>
#include <thread>
using namespace std::literals;
std::mutex mut1;
std::mutex mut2;
void funcA() {
std::cout << "Thread A trying to lock mutex 1...\n";
std::lock_guard<std::mutex> lck_guard1(mut1);
std::cout << "Thread A has locked mutex 1\n";
std::this_thread::sleep_for(50ms);
std::cout << "Thread A rying to lock mutex 2...\n";
std::lock_guard<std::mutex> lck_guard2(mut2);
std::this_thread::sleep_for(50ms);
std::cout << "Thread A releases all its locks\n";
}
void funcB() {
std::cout << "Thread B trying to lock mutex 2...\n";
std::lock_guard<std::mutex> lck_guard1(mut2);
std::cout << "Thread B has locked mutex 2\n";
std::this_thread::sleep_for(50ms);
std::cout << "Thread B rying to lock mutex 1...\n";
std::lock_guard<std::mutex> lck_guard2(mut1);
std::this_thread::sleep_for(50ms);
std::cout << "Thread B releases all its locks\n";
}
// The locks are never released, since they are waiting for each other
int main() {
std::thread thr1(funcA);
std::thread thr2(funcB);
thr1.join();
thr1.join();
}
Mutual Deadlock
- Can also occur when waiting for
- The result of a computation performed by another thread
- A message by another thread
- A GUI event produced by another thread
- The second most common problem in multi threading code
- Often caused by threads trying to lock mutexes in different orders
Deadlock Avoidance
- A simple way to avoid deadlock
- Both threads try to acquire the locks in the same order
- Thread A and thread B both try to lock mutex1 first
- The successful thread then tries to lock mutex2