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