2015-05-13 4 views
3

Примечание: Я ограничен .NET 3.5, поэтому я не могу использовать ManualResetEventSlim.Может ли EventWaitHandle иметь дело с ложными следами?

Должен ли я иметь дело с Spurious wakeups, делая что-то вроде этого:

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

Нет побочных пробуждений. Почти все программы для Windows сломались, если бы это было так. Вы сражаетесь с ветряными мельницами. Но да, функции синхронизации выполняют полный барьер памяти (который хорошо понимается, но нигде не документируется). – usr

+0

Я не согласен: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682052%28v=vs.85%29.aspx «Переменные условия подвержены ложным пробуждениям (те, которые не связаны с явным следом) и украденные пробуждения (другой поток удается запустить до разбуженного потока). Поэтому вам нужно перепроверить предикат (обычно в цикле while) после возвращения операции сна. " Также в .NET 4.0+ есть такой код: http://referencesource.microsoft.com/#mscorlib/system/threading/ManualResetEventSlim.cs,635 «// Loop для обработки ложных пробуждений от других ожиданий, которые будут отменены " –

+1

Событие не является переменной условия. Это не относится. Исходный код сообщает вам, что инфраструктура обрабатывает этот случай для вас. Поддельные пробуждения не подвержены коду пользователя. Это детали реализации, которые вы там выкопали. – usr

ответ

2

Нет никаких побочных пробуждений для событий (MRE, ARE и тонкие версии). Почти все программы Windows сломались бы, если бы существовали такие вещи с этими объектами. Вы сражаетесь с ветряными мельницами. Но да, многие функции синхронизации, включая события ожидания и настройки, выполняют полный барьер памяти (который хорошо понимается, но нигде не документируется). Переменные условия, чтобы разрешить ложные пробуждения (как состояние документов). Они не связаны с событиями.

Кроме того, почему возникли побочные пробуждения? Не имеет смысла с точки зрения API. Событие может просто зацикливаться внутри и скрыть побочные пробуждения от вас (действительно, MRESlim делает это). Я могу только повторить: почти все программы сломались. Это не реальность.

The docs say:

блокирует текущий поток до тех пор, пока ток WaitHandle принимает сигнал. Вызывающий этот метод блокирует бесконечно, пока текущий экземпляр не получит сигнал.

Эти утверждения были бы ложными, если бы ложные пробуждения должны существовать в контексте событий.

Вы неверно истолковали то, что видели. У вас есть ошибка, но это не вызвано событием. Техника reallyDone не требуется.

+0

Копаясь в исходном источнике, кажется, что 'WaitHandle' не поддерживается переменными условия, как вы упомянули в комментарии выше. Вместо этого они поддерживаются объектами Event, которые, как вы упомянули, не имеют побочных пробуждений. Более подробную информацию о объектах событий можно найти здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686915(v=vs.85).aspx –

 Смежные вопросы

  • Нет связанных вопросов^_^