Вопрос

Я наткнулся на этот интересный абзац в Документация по потоку Boost Сегодня:

void wait(boost::unique_lock<boost::mutex>& lock)

...

Эффекты:Атомарно вызываем lock.unlock() и блокируем текущий поток. Поток разблокируется при уведомлении с помощью вызова this->notify_one() или this->notify_all(), или лживо.Когда поток разблокируется (по какой бы то ни было причине), блокировка восстанавливается путем вызова lock.lock() прежде чем вернется вызов wait. Блокировка также восстанавливается путем вызова lock.lock(), если функция завершается с исключением.

Итак, что меня интересует, так это значение слова "ложно".Почему поток должен быть разблокирован по ложным причинам?Что можно сделать, чтобы решить эту проблему?

Это было полезно?

Решение

Эта статья Энтони Уильямса является особенно подробным.

Ложные пробуждения не могут быть предсказаны:они, по сути, случайны с точки зрения пользователя.Однако они обычно возникают, когда библиотека потоков не может надежно гарантировать, что ожидающий поток не пропустит уведомление.Поскольку пропущенное уведомление сделало бы переменную условия бесполезной, библиотека потоков выводит поток из режима ожидания вместо того, чтобы идти на риск.

Он также указывает на то, что вам не следует использовать timed_wait перегрузки, которые требуют определенной продолжительности, и обычно вам следует использовать версии, которые принимают предикат

Это ошибка новичка, и один это легко преодолеть с помощью простого правила:всегда проверяйте свой предикат в цикле при ожидании с условием переменная.Более коварная ошибка возникает из timed_wait().

Эта статья Владимира Пруса это тоже интересно.

Но зачем нам нужен цикл while, разве мы не можем написать:

if (!something_happened)
  c.wait(m);

Мы не можем.И убийственная причина в том, что 'wait' может вернуться без какого-либо вызова 'notify'.Это называется ложным пробуждением и явно разрешено POSIX.По сути, return только из 'wait' указывает, что общие данные могли измениться, так что данные должны быть оценены повторно.

Хорошо, так почему же это до сих пор не исправлено?Первая причина в том, что никто не хочет исправлять это.Перенос вызова в 'wait' в цикл очень желателен по нескольким другим причинам.Но эти причины требуют объяснения, хотя и ложные пробуждение - это молоток, который можно применить к любому студенту первого курса без неудачи.

Другие советы

Это сообщение в блоге дает основание для Linux, с точки зрения futex системный вызов, возвращающийся при доставке сигнала процессу.К сожалению, это больше ничего не объясняет (и действительно, запрашивает дополнительную информацию).

В Статья в Википедии о ложных пробуждениях (которые, кстати, являются концепцией для всего posix, не ограничиваясь boost) могут вас тоже заинтересовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top