Почему условные переменные иногда ошибочно просыпаются? - PullRequest
6 голосов
/ 28 апреля 2010

Я давно знал, что вы используете условную переменную

lock
while not task_done
  wait on condition variable
unlock

Потому что иногда условные переменные самопроизвольно просыпаются. Но я никогда не понимал, почему это так. В прошлом я читал, что создавать условную переменную, которая не имеет такого поведения, но не более того.

Итак ... зачем вам беспокоиться о ложном пробуждении при ожидании переменной условия?

Ответы [ 2 ]

3 голосов
/ 28 апреля 2010

Не так, что условная переменная будет ошибочно просыпаться; переменная условия будет активирована, только если она была передана из другого потока. Однако возможно, что к тому моменту, когда поток был перепланирован на выполнение, какой-то другой поток уже успел захватить ресурс, на котором вы ожидали, и поэтому необходимо перепроверить. Например, если группа потоков x, y, z ожидает некоторого ресурса R, который w ранее удерживал, и x, y, z, w обмениваются данными через переменную условия ... предположим, что w выполняется с R и сигнализирует x , у, г. Таким образом, x, y и z все будут удалены из очереди ожидания и помещены в очередь выполнения, которая будет запланирована для выполнения. Предположим, что сначала запланировано x ... так что затем он получает R, а затем его можно перевести в спящий режим, а затем можно запланировать y, и поэтому, когда y выполняется, ресурс R, для которого y ожидал ранее, все еще недоступен. , поэтому вам необходимо снова пойти спать. Затем z просыпается, и z также обнаруживает, что R все еще используется, поэтому z нужно снова вернуться в спящий режим и т. Д.

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

1 голос
/ 28 апреля 2010

Темы могут просыпаться без сигналов. Это называется ложным пробуждением . Тем не менее, точно почему они происходят, это вопрос, который, похоже, погряз в суевериях и неопределенности. Причины, которые я видел, включают побочный эффект от того, как работают реализации многопоточности, или намеренное добавление, чтобы заставить программистов правильно использовать циклы вместо условий вокруг wait.

...