Эта статья Энтони Уильямса особенно подробна.
Ложные следы не могут быть предсказаны:
они по существу случайны из
точка зрения пользователя. Тем не менее, они
обычно происходит, когда поток библиотеки
не может надежно гарантировать, что ожидание
Тема не пропустит уведомление.
Поскольку пропущенное уведомление
сделать переменную условия бесполезной,
библиотека потоков будит поток
от его ожидания, а не взять
риск.
Он также указывает, что вы не должны использовать перегрузки timed_wait
, которые занимают какое-то время, и вы должны обычно использовать версии, которые принимают предикат
Это ошибка новичка, и один
это легко преодолеть с помощью простого
правило: всегда проверяйте свой предикат в
цикл при ожидании с условием
переменная. Более коварная ошибка
из timed_wait ().
Эта статья Владимира Пруса тоже интересна.
Но зачем нам цикл while,
мы не можем написать:
if (!something_happened)
c.wait(m);
Мы не можем. И причина убийства в том, что «ждать» может
вернуться без какого-либо вызова «уведомить».
Это называется ложным пробуждением и является
явно разрешено POSIX.
По сути, возврат только из «ожидания»
указывает, что общие данные могут
изменились, так что данные должны быть
оценивается снова.
Хорошо, так почему это еще не исправлено?
Первая причина в том, что никто не хочет
починить это. Завершение вызова «ждать» в
петля очень желательна для нескольких
другие причины. Но эти причины
требуют объяснений, в то время как поддельные
пробуждение - это молоток, который можно применить
любому первокурснику без
потерпеть неудачу.