自动重置事件只是一个愚蠢的信号量
创始人
2025-06-29 22:31:47
0

当我们调用 CreateEvent 函数创建一个事件对象的时候,我们可以通过参数来指定这个事件对象是自动重置的,还是手动重置的。

对于一个手动重置的事件对象,它很容易理解:当事件未激发时,在此事件上的等待将一直挂起,而当事件被激发时,在此事件对象上的等待将会立即返回。上面的工作原则和有多少个线程正在等待此对象没有任何关系。所有线程对此对象的等待操作都是一致的,并且事件对象的状态也不会受到等待它的线程数量影响。

对于一个自动重置的事件对象,事情开始变得复杂了。

理解它的工作原理的最简单方法是:将它看做是一个最大计数为 1 的信号量。

此话怎讲?

当事件未激发时,在此事件上的等待的线程将一直挂起,而当事件被激发时,仅会只有一个等待线程结束等待,并且事件对象将会自动重置其状态为未激发态。结果就是:剩下的其他线程将会继续等待。从我们之前对 PulseEvent 的讨论来看,你可能已经知道了,如果有多个等待线程,则不确定将释放哪个等待线程。

使用自动重置事件的陷阱在于:你设置了已处于激发态的事件。由于事件只有两种状态(设置和重置),因此设置已设置的事件不起作用。如果使用事件来控制资源生产者/使用者模型,则设置已处于激发态的事件将导致你看起来 “丢失:了令牌。

请考虑以下场景模式。

但是,如果时机没有完全出来怎么办?如果使用者线程完成工作有点慢(或者生产者线程生成它的速度有点快),该怎么办:

请注意,生成者生成了三个工作项,但使用者只执行了其中的两个。第三个 SetEvent 没有效果,因为事件已经设置好了。(如果尝试将信号量的令牌计数增加到超过其最大值,则会遇到相同的问题。)如果希望唤醒数与集数匹配,则需要使用最大令牌计数与将支持的最大未完成工作项数一样高的信号量。

总结

了解你手上工具的使用方法,更加需要了解其局限性。永远在正确的场景下使用正确的工具,这确实挺难的。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...