Выбор ответа Middle Многопоточность и модель памяти спрашивают часто обновлено
Ожидание на condition_variable
Вопрос
Почему cv.wait(lock) нужно вызывать с предикатом или в цикле проверки условия?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Бывают ложные пробуждения и потерянные уведомления: условие нужно перепроверять. wait(lock, pred) эквивалентен while (!pred()) wait(lock);.
Варианты ответа
- Бывают ложные пробуждения и потерянные уведомления: условие нужно перепроверятьправильный ответ
- Без предиката
waitне компилируется: перегрузки без него в стандарте нет - Предикат ускоряет пробуждение: поток просыпается сразу, без планировщика
- Предикат нужен только для
notify_all, приnotify_oneбудит ровно один поток
Разбор
wait(lock, pred) эквивалентен while (!pred()) wait(lock);. Он защищает от ложных пробуждений (разрешены стандартом) и от потерянного уведомления: если условие уже выполнено, поток вообще не уснёт. Условие должно меняться под тем же мьютексом.
- Перегрузка без предиката существует, поэтому ошибка и встречается.
- Скорость пробуждения от предиката не зависит.
- Предикат нужен при любом способе уведомления.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Многопоточность и модель памяти»
- Найти потенциальный дедлок по порядку захвата мьютексов
- Пул потоков: кто и когда выполнит задачу
- Публикация данных через флаг
- Ловушка std::async
- Потокобезопасная ленивая инициализация
- Как избежать дедлока с двумя мьютексами
- lock_guard, unique_lock, scoped_lock
- Примитив синхронизации и задача