使用SendMessage()多线程

时间:2016-02-22 00:29:46

标签: c++ windows multithreading winapi message-queue

如果我将SendMessage()从不同的线程用于一个接收器,会发生什么?想象一下这样一种情况,当接收器仍在处理来自Thread1的消息而Thread2发送另一条消息时(使用SendMessage())。接收端会发生什么?是否停止执行Message1,处理Message2,在完成Message2后返回Message1?或者Message2是否等待Message1的结束?

2 个答案:

答案 0 :(得分:3)

基本规则是:线程调度跨线程发送消息的唯一时间是在该线程上调用消息检索功能(GetMessagePeekMessage等)。消息检索功能首先检查任何跨线程发送的消息,一个接一个地分派它们,然后继续从线程的消息队列中检索消息。

这有两个后果:

  • 当接收线程未处理 1)任何排队的消息时,将调度跨线程发送的消息。
  • 当接收线程未处理 1)任何其他跨线程发送消息时,将调度跨线程发送消息。

在您的特定示例中,接收方将继续处理Message1直到完成,并在下次调用消息检索功能时继续调度Message2。

此规则有一个值得注意的例外:等待SendMessage返回的线程可以调度入站的跨线程发送消息 2)。这意味着有可能重新进入。再举一遍你的例子,假设Message1的消息处理程序在某些时候调用SendMessage,很可能是,在继续处理Message1之前调度Message2。

总结一下:

  • 在接收线程上串行发送跨线程发送的消息。
  • 当线程调度跨线程发送的消息时,有几个明确定义的时间。
  • 虽然从不同时处理跨线程发送的消息,但没有原子性规则;为重新做好准备。

<小时/> 1)假设调用消息检索功能不是正常消息处理的一部分 2)详情请参阅When can a thread receive window messages?

答案 1 :(得分:1)

我假设问题是关于发送到特定窗口的消息,即除NULL或HWND_BROADCAST之外的HWND,并且该窗口由属于同一进程的线程拥有。

在这种情况下,创建目标窗口的线程将在下次使用包含给定窗口的过滤器调用GetMessage时接收消息。发送线程将被阻塞,直到接收线程实际完成消息的处理。

如果在处理来自Thread1的消息时,接收线程再次调用GetMessage / DispatchMessage,那么任何待处理消息(包括可能由Thread2发送的消息)将在该点处理,然后控制将返回处理来自线程1。

来自SendMessage function的文档:

  

如果指定的窗口是由调用线程创建的,则窗口过程将作为子例程立即调用。如果指定的窗口是由其他线程创建的,则系统会切换到该线程并调用相应的窗口过程。仅当接收线程执行消息检索代码时才处理线程之间发送的消息。发送线程被阻塞,直到接收线程处理该消息。