Как избавиться от deadlock при использовании mutex?
1,00
р.
р.
В первом потоке так: mutex1.lock() mutex2.lock() Во втором так: mutex2.lock() mutex1.lock() Проблема в том, что эти мьютексы находятся в разных классах, скажем Parent и Child, они вызывают методы друг друга, но ничего не знают о внутреннем устройстве друг друга (но если надо, их можно научить, но только как?). Мьютексы защищают какие-то внутренние данные соответствующих классов. Это происходит при вложенных вызовах: Callstack - thread 1 10. mutex2.lock() 9. child.method2() 8. mutex1.lock() 7. parent.method1() .... Callstack - thread 2 10. mutex1.lock() 9. parent.anotherMethod() 8. mutex2.lock() 7. child.someMethod() .... Может есть какой-то паттерн для такой проблемы.
Ответ Чтобы избавиться от дедлоков, можно использовать функцию std::lock. Она принимает несколько мьютексов, и лочит их с помощью специального алгоритма который позволяет избежать дедлоков. Применять ее следует таким образом: std::lock(mutex1, mutex2) std::lock_guard guard1(mutex1, std::adopt_lock) std::lock_guard guard2(mutex2, std::adopt_lock) Или наоборот, сначала создать lock_guard, а потом залочить: std::lock_guard guard1(mutex1, std::defer_lock) std::lock_guard guard2(mutex2, std::defer_lock) std::lock(mutex1, mutex2)