事件 (同步原语)
计算机科学中的一种同步机制
事件作为一种同步原语,是电脑科学中的一种同步机制,用来指示等待中的进程特定条件已经变为真。
事件对象一般具有下述操作:
- wait - 执行中的线程被挂起直到事件为真。如果执行wait时事件已为真,则空操作。
- set - 设置事件状态为真,所有等待此事件的进程变为可调度。
- clear - 设置事件状态为假。
事件类似于管程中的条件变量。
Windows系统
Microsoft Windows操作系统提供的事件内核对象,状态为signaled对应于状态为真;使用WaitForObject及相关系统函数实现wait操作,SetEvent系统函数实现set操作,ResetEvent系统函数实现clear操作。
在创建事件对象时可以设置为“自动重置事件”或“手动重置事件”。当一个手动重置事件被触发的时候,正在等待该事件的所有线程都将变成可调度状态;而当一个自动重置事件对象被触发的时候,只有一个正在等待该事件的线程会变成可调度状态,随后该事件对象自动变为未触发态,但是如果被触发时没有等待该事件对象的线程,那么该事件对象会保持触发状态,直至遇到第一个等待该事件对象的线程。
Windows API还有一个函数PulseEvent,会把一个正在等待该事件对象的线程变成可调度状态,事件对象随即保持未触发状态;如果函数调用时没有等待该事件对象的线程那么等效于什么都不做。可见,PulseEvent并不等价于触发自动重置事件对象。MSDN已经指出不要使用PulseEvent,[1]因为无法保证一个正在等待该事件对象的线程一定会被唤醒,其根源是挂起的线程可被系统调度执行内核级异步过程调用,这种事无法预测也无法察觉,此时发生PulseEvent就无法唤醒这个正在执行内核级异步过程调用的线程。
C++语言标准
C++语言标准已经实现了这种并发编程的同步事件。在C++11的STL中增加了future与promise两种类模板,分别表示同步事件的消费者与生产者。
参考文献
- Event Objects(页面存档备份,存于互联网档案馆), Microsoft Developer Network
- Thread Synchronization Mechanisms in Python(页面存档备份,存于互联网档案馆)
- ^ PulseEvent function in MSDN: "Therefore, PulseEvent is unreliable and should not be used by new applications.". [2017-09-04]. (原始内容存档于2017-09-04). (页面存档备份,存于互联网档案馆)