Windows 消息队列是否以 FIFO 方式处理消息?

Is the Windows message queue handle the message in an FIFO way?

我假设当我们调用 SendMessage & PostMessage, the message will be handled in the same order as the Send/PostMessage called. But as the document 时说如果当前线程是正确的 SendMessage 将执行函数。

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine.

所以在下面的例子中:

PostMessage(currentThreadWindow, postMsg, ...) // line 1
SendMessage(currentThreadWindow, sendMsg...) // line 2

sendMsg 将在 postMsg 之前处理。

传递给 SendMessagePostMessage 的消息是否保持顺序?

So does message passed to SendMessage and PostMessage keep the order?

你已经知道这个问题的答案,如果你是 sending/posting 一条消息到调用线程拥有的 window: 对 SendMessage 的调用完全绕过了消息队列, 并立即调用 window 过程,因此此消息将始终在 posted 消息之前处理。

如果您跨越线程边界,您将不再获得任何保证。即使入站跨线程消息在消息队列中当前的任何消息之前分派,您也无法控制调用线程何时被抢占。如果它在对 PostMessageSendMessage 的调用之间被抢占,则 posted 消息很可能在发送消息之前被处理。如果调用线程在这些调用之间没有被抢占,您仍然得不到任何保证。这取决于并发执行的接收线程,是否先处理 posted 或发送的消息。

更复杂的是,线程也可以在其他时间接收消息(参见 When can a thread receive window messages?)。在等待出站 SendMessage 调用的结果时,线程仍会收到入站跨线程消息。换句话说:在继续处理下一条消息之前,您甚至不能依赖消息作为一个整体处理的事实。您的 window 程序需要准备好重新进入。

您可以信赖的是,几条 posted 消息的相对顺序保持不变。如果您 post 2 条消息,则第一条消息将在第二条消息之前处理。这些消息仍然可以与其他 posted 消息穿插。