EventWaitHandle имеет дело с ложными пробуждениями?
Примечание. Я ограничен.NET 3.5, поэтому не могу использовать ManualResetEventSlim
,
Должен ли я иметь дело с ложными пробуждениями, когда делаю что-то вроде этого:
var waitHandle = new EventWaitHandle();
new Thread(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(5));
waitHandler.Set();
});
waitHandle.WaitOne();
Если да, установлен ли правильный барьер памяти при вызове Set
и / или WaitOne
так что это будет безопасно:
var reallyDone = false;
var waitHandle = new EventWaitHandle();
new Thread(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(5));
reallyDone = true;
waitHandler.Set();
});
while (!reallyDone)
waitHandle.WaitOne();
В частности, возможно ли, что основной поток в этом примере может не видеть, что reallyDone
имеет значение true из-за переупорядочения команд или кэширования? Есть ли reallyDone
должны быть нестабильны в этом случае или это не нужно?
1 ответ
Нет никаких ложных пробуждений для событий (MRE, ARE и тонкие версии). Почти все программы Windows сломались бы, если бы что-то было с этими объектами. Вы боретесь с ветряными мельницами. Но да, многие из функций синхронизации, включая события ожидания и установки, выполняют полный барьер памяти (что хорошо понятно, но нигде не задокументировано). Переменные условия, чтобы разрешить ложные пробуждения (как состояние документов). Они не связаны с событиями.
Кроме того, почему были бы ложные пробуждения? Не имеет смысла с точки зрения API. Событие может просто зациклиться внутри и скрыть ложные пробуждения от вас (действительно, MRESlim делает это). Я могу только повторить: почти все программы сломаются. Это не реальность.
Блокирует текущий поток, пока текущий WaitHandle не получит сигнал. Вызывающая сторона этого метода блокируется бесконечно, пока текущий экземпляр не получит сигнал.
Эти заявления были бы ложными, если бы в контексте событий существовали ложные пробуждения.
Вы неправильно понимаете то, что видели. У вас есть ошибка, но она не вызвана событием. reallyDone
Техника не требуется.