有三个线程和自动重置事件。当第二个和第三个线程正在等待这个事件时,第一个线程调用 SetEvent 两次。系统是否保证两个等待线程都会唤醒?
我在 MSDN 中阅读了 .NET Framework AutoResetEvent 类的注释:不能保证每次调用 Set 方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在一个线程被释放之前,那么只有一个线程被释放。就好像第二次通话没有发生一样。
Win32 API 是否正确?
有三个线程和自动重置事件。当第二个和第三个线程正在等待这个事件时,第一个线程调用 SetEvent 两次。系统是否保证两个等待线程都会唤醒?
我在 MSDN 中阅读了 .NET Framework AutoResetEvent 类的注释:不能保证每次调用 Set 方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在一个线程被释放之前,那么只有一个线程被释放。就好像第二次通话没有发生一样。
Win32 API 是否正确?
考虑以下场景:
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
在需要时将事件设置回非信号状态。
还有其他选项,例如使用信号量来控制访问,或者如果您计划只等待很短的时间(自旋锁性能),则使用关键部分,但手动重置事件似乎是可行的方法。通常,检查同步对象。