【问题标题】:Does a SendMessage() call from another thread posts a message to the message queue?来自另一个线程的 SendMessage() 调用是否将消息发布到消息队列?
【发布时间】:2015-03-13 00:26:51
【问题描述】:

我已经阅读了关于从另一个线程调用SendMessage() 的两个相互矛盾的概念:

  • 首先是消息会被投递到消息队列中。

  • 二是会直接调用SendMessage()。但是调用线程会阻​​塞,上下文切换到UI线程,然后窗口过程被调用,当它返回时,调用线程解除阻塞,上下文切换回它。

那么哪个是正确的?

【问题讨论】:

  • SendMessage() 从不发布到消息队列。 其中一些 将自动从调用线程封送到拥有该窗口的线程。但这仅适用于系统消息,Windows 本身知道的那种。不是可以依赖的东西。
  • SendMessage 中关于nonqueued messages 的链接可能有助于澄清这一点。基本上,消息以某种未指定的方式发送到目标线程,实际上可能是通过 some 类的队列 - 但它绕过了程序员可以直接操作的常规线程消息队列。跨度>

标签: c++ c winapi


【解决方案1】:

在我看来,SendMessage 的文档相当清楚:

如果指定的窗口是由调用线程创建的,则窗口过程作为子程序立即被调用。如果指定的窗口是由不同的线程创建的,则系统切换到该线程并调用适当的窗口过程。只有当接收线程执行消息检索代码时,才会处理线程之间发送的消息。发送线程被阻塞,直到接收线程处理完消息。

使用SendMessage 发送的消息永远不会放在消息队列中。换句话说,你的第一个要点是完全错误的。

在跨线程发送消息的情况下,它在拥有窗口的线程中调度,通常通过在接收线程的消息循环中调用GetMessage。还有其他功能,例如PeekMessageSendMessage 等,将发送消息。

【讨论】:

  • "线程间发送的消息只有在接收线程执行消息检索代码时才被处理" 为什么我要在没有消息的情况下检索消息?!
  • 典型的消息循环调用GetMessage。如果队列中没有任何内容,该调用将阻塞。当另一个线程向GetMessage 中阻塞的线程发送消息时,接收线程会唤醒,分派发送的消息,然后继续等待队列中的消息。
  • @Martin:MSDN 描述的是合约,而不是实现。在合同方面,您认为缺少哪些信息?
  • @IInspectable I 发现 25 年来缺少的是最轻微的看似合理的语言,表明它实际上按照描述的方式工作,从 David 的 cmets 中可以清楚地看出它实际上没有。正如 Martin 所说,他们准备好具体到“作为子程序”,这是实现,而不是合同,但“切换到该线程”只是 waffle。
  • @IInspectable 什么都没有,。问题是由松散的实施影响引起的 FUD。例如,“系统切换到该线程”强烈暗示该切换是 SendMessage 调用的主动操作(事实并非如此,因为目标线程必须能够响应使用的任何信号)。
猜你喜欢
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 2012-03-25
  • 2010-12-19
相关资源
最近更新 更多