Выбор ответа Middle Многопоточность и модель памяти спрашивают часто обновлено

Ожидание на condition_variable

Вопрос

Почему cv.wait(lock) нужно вызывать с предикатом или в цикле проверки условия?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Бывают ложные пробуждения и потерянные уведомления: условие нужно перепроверять. wait(lock, pred) эквивалентен while (!pred()) wait(lock);.

Варианты ответа

  1. Бывают ложные пробуждения и потерянные уведомления: условие нужно перепроверятьправильный ответ
  2. Без предиката wait не компилируется: перегрузки без него в стандарте нет
  3. Предикат ускоряет пробуждение: поток просыпается сразу, без планировщика
  4. Предикат нужен только для notify_all, при notify_one будит ровно один поток

Разбор

wait(lock, pred) эквивалентен while (!pred()) wait(lock);. Он защищает от ложных пробуждений (разрешены стандартом) и от потерянного уведомления: если условие уже выполнено, поток вообще не уснёт. Условие должно меняться под тем же мьютексом.

  • Перегрузка без предиката существует, поэтому ошибка и встречается.
  • Скорость пробуждения от предиката не зависит.
  • Предикат нужен при любом способе уведомления.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.