Windows消息及其确定性属性

时间:2016-06-01 22:22:44

标签: windows message-queue

我想确认一下我认为的真实情况。当我使用Windows SendMessage()时,这是一个确定性调用,因为它将立即执行(在处理消息之前不会返回),而不是PostMessage(),这是非确定性的,因为它可以被抢占在那个时刻恰好在队列中的任何其他消息(实际上它只有在它到达消息循环之后才会被执行)。

这是一个公平的评估,还是我错过了什么?

1 个答案:

答案 0 :(得分:0)

对于进程内调用,这基本上是正确的。跨进程SendMessage的工作方式类似,但在接收方进程调用GetMessage(或其亲属)之前,消息的处理才会开始。

您的UI线程有一个消息泵,类似于:

while (GetMessage(&msg))
  DispatchMessage(&msg);

PostMessage导致将消息放入消息队列。 GetMessage从队列中删除最旧的消息(FIFO *)。

DispatchMessage导致与消息的目标窗口关联的WndProc与消息一起被调用。

SendMessage基本上绕过这个链并直接调用WndProc(或多或少)。

许多标准窗口消息导致一组SendMessage调用,其中发送一条消息发送另一条消息发送另一条消息。该链通常被称为“当前发送”。如果您需要在链中处理您的消息,请使用SendMessage。如果在当前调度完成后需要对其进行处理,请使用PostMessage。

您可以使用Spy++之类的工具查看正在运行的Windows消息,或使用消息操作顺序调试您遇到的问题。

[*]它不是严格意义上的FIFO队列,因为某些类型的消息(即计时器,鼠标​​,键盘)实际上并未发布到队列中,而是在运行中生成。为简单起见,您可以将其视为FIFO。