Сколько нужно Mutex, чтобы создать Deadlock
1️⃣ Как кратко ответить
Для создания deadlock (взаимной блокировки) необходимо как минимум два mutex. Deadlock возникает, когда два или более потока блокируют ресурсы в таком порядке, что каждый поток ожидает освобождения ресурса, удерживаемого другим потоком.
2️⃣ Подробное объяснение темы
Deadlock — это ситуация, в которой два или более потока не могут продолжить выполнение, потому что каждый из них ожидает освобождения ресурса, удерживаемого другим потоком. Это может произойти, когда потоки блокируют ресурсы в неправильном порядке.
Пример с двумя mutex
Рассмотрим пример, где два потока используют два mutex для синхронизации доступа к ресурсам:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutex1;
std::mutex mutex2;
void thread1() {
// Поток 1 блокирует первый mutex
mutex1.lock();
std::cout << "Thread 1: locked mutex1" << std::endl;
// Имитация работы
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Поток 1 пытается заблокировать второй mutex
mutex2.lock();
std::cout << "Thread 1: locked mutex2" << std::endl;
// Освобождение ресурсов
mutex2.unlock();
mutex1.unlock();
}
void thread2() {
// Поток 2 блокирует второй mutex
mutex2.lock();
std::cout << "Thread 2: locked mutex2" << std::endl;
// Имитация работы
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Поток 2 пытается заблокировать первый mutex
mutex1.lock();
std::cout << "Thread 2: locked mutex1" << std::endl;
// Освобождение ресурсов
mutex1.unlock();
mutex2.unlock();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
Объяснение кода
-
Создание двух mutex:
std::mutex mutex1;иstd::mutex mutex2;— это объекты синхронизации, которые используются для управления доступом к общим ресурсам. -
Функция
thread1:- Блокирует
mutex1с помощьюmutex1.lock();. - Выводит сообщение о блокировке
mutex1. - Имитация работы с помощью
std::this_thread::sleep_for. - Пытается заблокировать
mutex2с помощьюmutex2.lock();. - Выводит сообщение о блокировке
mutex2. - Освобождает оба mutex с помощью
unlock().
- Блокирует
-
Функция
thread2:- Блокирует
mutex2с помощьюmutex2.lock();. - Выводит сообщение о блокировке
mutex2. - Имитация работы с помощью
std::this_thread::sleep_for. - Пытается заблокировать
mutex1с помощьюmutex1.lock();. - Выводит сообщение о блокировке
mutex1. - Освобождает оба mutex с помощью
unlock().
- Блокирует
-
Функция
main:- Создает два потока
t1иt2, которые выполняют функцииthread1иthread2. - Ожидает завершения потоков с помощью
join().
- Создает два потока
Почему возникает deadlock
В этом примере deadlock возникает, потому что:
- Поток 1 блокирует
mutex1и ожидаетmutex2. - Поток 2 блокирует
mutex2и ожидаетmutex1.
Оба потока ждут друг друга, и ни один из них не может продолжить выполнение. Это классический пример deadlock, который может быть решен путем изменения порядка блокировки mutex или использования других механизмов синхронизации, таких как std::lock или std::scoped_lock, которые предотвращают взаимные блокировки.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться