Почему условные переменные иногда ошибочно просыпаются?

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

lock
while not task_done
  wait on condition variable
unlock

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

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

6
задан bdonlan 8 October 2010 в 17:27
поделиться

2 ответа

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

1
ответ дан 17 December 2019 в 07:02
поделиться

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

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

3
ответ дан 17 December 2019 в 07:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: