MiddleДебаггингЧастоЕщё не отвечали
Почему этот порядок захвата мьютексов вызывает дедлок и как исправить?
Два потока выполняют t1 и t2 одновременно, и программа иногда зависает.
std::mutex m1, m2;
void t1() { std::lock_guard<std::mutex> a(m1); std::lock_guard<std::mutex> b(m2); }
void t2() { std::lock_guard<std::mutex> a(m2); std::lock_guard<std::mutex> b(m1); }
Найдите и исправьте ошибку.
Дедлок из-за инверсии порядка блокировок: t1 захватывает m1, затем m2; t2 — m2, затем m1. Если каждый возьмёт свой первый мьютекс одновременно, второй не достанется никому. Решение: захватывать в одном глобальном порядке или std::scoped_lock lk(m1, m2) (C++17), запирающий оба атомарно.
- ✗Считать, что короткие критические секции не могут привести к дедлоку
- ✗Путать это с повторным захватом нерекурсивного мьютекса
- ✗Думать, что lock_guard откладывает захват до выхода из области видимости
- →Как
std::scoped_lockизбегает дедлока при захвате нескольких мьютексов? - →Что такое дисциплина единого порядка блокировок и почему она работает?