两者MsgWaitForMultipleObjects[Ex]
和WaitForMultipleObjects[Ex]
内部调用相同的api -KeWaitForMultipleObjects
不同的 in -MsgWaitForMultipleObjects[Ex]
将事件(在前面,在 0 索引处)添加到对象句柄数组。因为KeWaitForMultipleObjects
对最大对象数有限制MAXIMUM_WAIT_OBJECTS
,所以同样的限制有 andWaitForMultipleObjects[Ex]
和MAXIMUM_WAIT_OBJECTS - 1
for MsgWaitForMultipleObjects[Ex]
(因为使用了额外的 +1 事件对象)
仅存在 2 WAIT_TYPE
- 要么WaitAll
,表示所有指定的对象必须在等待满足之前达到信号状态;或WaitAny
,表示任何一个对象必须在等待得到满足之前达到信号状态。
当我们等待对象发出信号时 - 在我们开始等待之前或之后处于信号状态的对象并不重要。无论如何,我们不会错过信号状态。当然,如果我们不手动将对象重置为不发出信号状态。但这已经是程序逻辑的问题,与等待 api 无关
连续的事件序列
这里不存在任何序列。每个对象都可以处于两种状态(有信号或无信号),我们可以等待所有或任何处于信号状态的对象。如果您等待任何 - 首先将发出信号的对象取决于具体情况。
Windows 是否对消息进行排队,以便应用程序不会错过任何事件?
根本没有任何消息。仅存在内部带有DISPATCHER_HEADER
(查看wdm.h)的对象。等待 api 检查SignalState
,DISPATCHER_HEADER
如果它已经设置 - 返回控制(如果我们等待单个对象或任何对象当然)。if not - 插入线程WaitListHead
(这是双链表,其中可以是多个线程,等待这个对象,并从win8开始 - WaitCompletionPacket的对象。当对象进入信号状态时(SignalState
设置为非零)。系统首先唤醒(SynchronizationEvent)或所有(NotificationEvent,其他对象类型)等待线程WaitListHead
(再次基于 waitall 或等待任何)。如果WaitCompletionPacket - 它排队到 iocp
再一次 - 我们没有错过(如果没有再次自行重置对象)