EventWaitHandle 是否必须处理虚假唤醒?

Does EventWaitHandle have to deal with spurious wakes?

注意:我受限于 .NET 3.5,所以我不能使用 ManualResetEventSlim

做这样的事情时我是否必须处理 Spurious wakeups:

var waitHandle = new EventWaitHandle();
new Thread(() =>
{
    Thread.Sleep(TimeSpan.FromSeconds(5));
    waitHandler.Set();
});
waitHandle.WaitOne();

如果是这样,调用 Set and/or 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 是否需要易失性还是​​不必要的?

事件(MRE、ARE 和 slim 版本)没有虚假唤醒。如果这些对象存在这样的问题,几乎所有 Windows 程序都会中断。你在和风车搏斗。但是,是的,包括等待和设置事件在内的许多同步功能都执行完整的内存屏障(这很容易理解,但没有记录)。允许虚假唤醒的条件变量(如文档所述)。它们与事件无关。

另外,为什么会有虚假唤醒?从 API 的角度来看没有意义。该事件可以在内部循环并向您隐藏虚假唤醒(实际上,MRESlim 就是这样做的)。我只能重复一遍:几乎所有程序都会中断。那不是现实。

The docs say:

Blocks the current thread until the current WaitHandle receives a signal. The caller of this method blocks indefinitely until the current instance receives a signal.

如果在事件上下文中存在虚假唤醒,这些陈述将是错误的。

您误解了所见。你有一个错误,但它不是由事件引起的。不需要 reallyDone 技术。