windows WaitForMultipleObjects MsgWaitForMultipleObjects的区别。

问题描述 投票:-2回答:1

我想知道这两者之间的区别 MsgWaitForWaitFor 功能。

1) 我明白 MsgWaitFor 正在消息循环下运行,而 WaitFor 没有?2)是否 MsgWaitFor 对于一个需要接收一连串事件的应用程序来说,哪个函数更好?Windows是否会将消息排成队列,这样应用程序就不会错过任何事件?AB 这种情况经常发生。应用程序将打开一个线程。

while (1) {
  ret = WaitForMultipleObjects(...); // wait for events A and B
  if (ret == WAIT_OBJECT_0) {
    process_event();
  }
}

问题是,当线程忙于处理的时候,也就是说它目前没有被阻断 WaitForMultipleObjects. 在回到等待之前,线程如何避免错过事件?

windows winapi events waitforsingleobject
1个回答
0
投票

我想了解MsgWaitFor和WaitFor函数的区别。

主要的区别是: 1)MsgWaitFor是在消息循环下运行的,而WaitFor则不是,我想了解MsgWaitFor和WaitFor函数的区别。MsgWaitForMultipleObjectsMsgWaitForMultipleObjectsEx 除了以下对象类型外,还可以等待消息(在消息队列中)。

  • 变更通知
  • 控制台输入
  • 事件
  • 内存资源通知
  • 缪特克斯
  • 流程
  • Semaphore
  • 主题
  • 等待时间

所以,如果你有一个创建窗口的线程,就使用 MsgWaitForMultipleObjectsMsgWaitForMultipleObjectsEx而不是 WaitForMultipleObjectsEx.

问题是,当线程忙于处理时,也就是说它目前没有被WaitForMultipleObjects阻塞。线程在回到等待之前,如何避免错过事件?

訊息 有队列,并且队列有一个长度(10,000条张贴信息). 所以当处理消息太慢时, PostMessage 可能失败 ERROR_NOT_ENOUGH_QUOTA. 但对于接收端,你不会错过消息,你可以逐一处理排队的消息。

事件 对象没有队列,它有两个状态。signalednonsignaled. 设置已经设置的事件没有任何效果。. 因此,如果这是一个手动复位的事件对象,它仍然是一个 signaled 直到它被明确设置为 nonsignaledResetEvent 功能。有可能在设置端而不是检查端出现失误。


0
投票

两个 MsgWaitForMultipleObjects[Ex]WaitForMultipleObjects[Ex] 内部调用同一个api - KeWaitForMultipleObjects

不同的是 MsgWaitForMultipleObjects[Ex] 在对象句柄数组中添加事件(在前面,0索引处),因为 KeWaitForMultipleObjects 对对象的最大数量限制为 MAXIMUM_WAIT_OBJECTS,同样的限制有和 WaitForMultipleObjects[Ex]MAXIMUM_WAIT_OBJECTS - 1 对于 MsgWaitForMultipleObjects[Ex] (因为使用了额外的+1事件对象)

只存二 WAIT_TYPE - 要么 WaitAll表示所有指定的对象必须在满足等待之前达到一个信号状态;或 WaitAny表示任何一个对象在等待之前必须达到信号状态。

当我们等待对象进入信号状态时--在我们开始等待之前或之后,对象是否处于信号状态并不重要,反正我们不会错过信号状态。

排列式

这里不存在任何顺序。每个对象都可以处于2个状态(有信号或无信号),我们可以等待所有或任何处于信号状态的对象。如果你等待任何一个对象--哪个对象先被信号化取决于具体的情况。

Windows是否会将消息排队,这样应用程序就不会错过任何事件?

完全没有任何消息。DISPATCHER_HEADER (看进去 wdm.h)里面,等待api检查 SignalStateDISPATCHER_HEADER 如果已经设置了 - 返回控制权(当然如果我们等待单个对象或任何对象)。WaitListHead (这是一个双链接的列表,其中可以有多个线程,这些线程等待这个对象,并从win8开始------)。WaitCompletionPacket的 当对象进入信号状态时(SignalState 设置为非零)。系统先唤醒 (SynchronizationEvent)或全部(NotificationEvent,其他对象类型)中的等待线程。WaitListHead (同样基于waitall或wait any).万一是 等待完成包 - 它排到了iocp

所以,我们再一次什么都没有错过(如果不是自己再次重置对象)。

© www.soinside.com 2019 - 2024. All rights reserved.