注意:我仅限于.NET 3.5,所以不能使用ManualResetEventSlim
。
做这样的事情时,我是否必须处理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
是否需要保持易失性? 最佳答案
没有虚假的事件唤醒(MRE,ARE和苗条版本)。如果这些对象发生这种事情,几乎所有Windows程序都会中断。你在打风车。但是是的,许多同步功能(包括等待事件和设置事件)执行完整的内存屏障(众所周知,但未在任何地方记载)。条件变量以允许虚假唤醒(如docs所述)。它们与事件无关。
另外,为什么会有虚假的唤醒?从API的角度来看没有任何意义。该事件可能会在内部循环并向您隐藏虚假的唤醒(实际上,MRESlim会这样做)。我只能重复一遍:几乎所有程序都会中断。那不是现实。
The docs say:
阻塞当前线程,直到当前的WaitHandle接收到信号为止。
此方法的调用者无限期地阻塞,直到当前实例接收到信号为止。
如果在事件的上下文中存在虚假唤醒,则这些陈述将为假。
您误解了所见。您有一个错误,但不是由事件引起的。不需要reallyDone
技术。
关于c# - EventWaitHandle是否必须处理虚假唤醒?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30223042/