Вступить в клуб →
средняявопросLinux, многопоточность и сеть

Два мьютекса захватываются в разном порядке: как убрать взаимную блокировку

Сервис изредка полностью перестаёт отвечать. В стеках потоков видно ожидание на мьютексах:

void move_a_to_b() {
    std::lock_guard<std::mutex> l1(m_a);
    std::lock_guard<std::mutex> l2(m_b);
    // ...
}

void move_b_to_a() {
    std::lock_guard<std::mutex> l1(m_b);
    std::lock_guard<std::mutex> l2(m_a);
    // ...
}

Выберите способы, которые действительно устраняют взаимную блокировку.

правильных вариантов может быть несколько

  • Ввести единый порядок захвата и соблюдать его во всех функциях, работающих с этой парой мьютексов
  • Захватывать оба мьютекса одной операцией, специально предназначенной для нескольких блокировок сразу
  • Заменить обычный мьютекс на рекурсивный, чтобы повторный захват не приводил к остановке потока
  • Добавить небольшую задержку перед захватом второго мьютекса, чтобы потоки расходились по времени
  • Повысить приоритет потока, который чаще выполняет move_a_to_b, чтобы он успевал захватить оба мьютекса

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела