0

有三个线程和自动重置事件。当第二个和第三个线程正在等待这个事件时,第一个线程调用 SetEvent 两次。系统是否保证两个等待线程都会唤醒?

我在 MSDN 中阅读了 .NET Framework AutoResetEvent 类的注释:不能保证每次调用 Set 方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在一个线程被释放之前,那么只有一个线程被释放。就好像第二次通话没有发生一样。

Win32 API 是否正确?

4

1 回答 1

3

考虑以下场景:

Event Signaled | Thread 1   | Thread 2      | Thread 3
---------------------------------------------------------
false          | SetEvent() |               |            
true           |            |               |            
true           |            | Wait Complete |            
false          |            |               |            
false          | SetEvent() |               |            
true           |            |               |            
true           |            |               | Wait Complete
false          |            |               |            

成功

Event Signaled | Thread 1   | Thread 2      | Thread 3
---------------------------------------------------------
false          | SetEvent() |               |            
true           |            |               |  
true           | SetEvent() |               |            
true           |            |               |            
true           |            | Wait Complete |            
false          |            |               |            
false          |            |               | Wait does not complete
false          |            |               |    

失败的

根据在特定时间执行哪个线程,您可能会也可能不会完成对其他线程的等待。

您应该将事件更改为手动重置事件,以确保所有线程都将完成等待,并ResetEvent在需要时将事件设置回非信号状态。

还有其他选项,例如使用信号量来控制访问,或者如果您计划只等待很短的时间(自旋锁性能),则使用关键部分,但手动重置事件似乎是可行的方法。通常,检查同步对象

于 2012-12-04T13:02:06.653 回答