Ложное пробуждение - Spurious wakeup

А ложное пробуждение происходит, когда поток просыпается от ожидания переменная состояния об этом сигнализировали, только чтобы обнаружить, что условие, которого он ждал, не выполнено. Это называется ложным, потому что нить, казалось бы, была разбужена без причины. Но ложные пробуждения не происходят без всякой причины, они обычно случаются, потому что между моментом, когда переменная условия была сигнализирована, и когда ожидающий поток, наконец, запустился, другой поток запустил и изменил условие. Был состояние гонки между потоками, с типичным результатом, что иногда поток, пробуждающийся по переменной условия, запускается первым, выиграв гонку, а иногда он бежит вторым, проигрывая гонку.

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

Чтобы обеспечить гибкость реализации при работе с ошибочными состояниями и гонками внутри операционной системы, переменным условия также может быть разрешено возвращаться из ожидания, даже если не было сигнала, хотя неясно, сколько реализаций на самом деле это делают. В реализации переменных состояния Solaris ложное пробуждение может происходить без сигнализации условия, если процесс сигнализируется; системный вызов ожидания прерывается и возвращается EINTR.[2]Реализация условных переменных pthread в Linux гарантирует, что этого не произойдет.[3][4]

Поскольку ложное пробуждение может произойти всякий раз, когда есть гонка и, возможно, даже при отсутствии гонки или сигнала, когда поток пробуждается по переменной условия, он всегда должен проверять, удовлетворяется ли искомое условие. Если это не так, он должен вернуться в режим сна по переменной условия, ожидая другой возможности.

Рекомендации

  1. ^ Раймонд Чен (1 февраля 2018 г.). «Ложные пробуждения в переменных состояния Win32». Получено 9 мая, 2020.
  2. ^ «Прерванное ожидание переменных условий (только потоки Solaris)». Корпорация Oracle. Получено 9 мая, 2020.
  3. ^ "pthread_cond_wait (3) - страница руководства Linux". die.net. Получено 9 мая, 2020. Эти функции не должны возвращать код ошибки [EINTR].
  4. ^ «pthread_cond_timedwait, pthread_cond_wait - ждать по условию». Открытая группа. 2018. Получено 9 мая, 2020.