【发布时间】:2011-07-12 08:52:09
【问题描述】:
Mfc 提供工作线程和 UI 线程。 UI 线程启用了消息接收功能(发送、发布)。是否可以让工作线程也接收消息。
【问题讨论】:
-
那为什么不使用 UI 线程呢?无论名称如何,您都不必包含任何 UI 内容。事实上,比我更了解的人建议将所有 UI 内容放在主线程中,因此 UI 线程将是“带有消息泵的辅助线程”。
标签: multithreading visual-c++ mfc
Mfc 提供工作线程和 UI 线程。 UI 线程启用了消息接收功能(发送、发布)。是否可以让工作线程也接收消息。
【问题讨论】:
标签: multithreading visual-c++ mfc
反复调用CWinThread::PumpMessage(),直到它返回WM_QUIT消息。
【讨论】:
看来您需要一个线程,它可以处理来自另一个线程的多条消息。另一个线程将向该线程的消息队列添加消息。好吧,在这种情况下,您可以使用PeekMessage 启动一个循环,最终会创建一个隐藏窗口,然后使用GetMessage 获取消息。其他线程将使用 PostThreadMessage 和线程 ID(具有 Peek/GetMessage 的那个)和消息代码 LPARAM、WPARAM.
就像(语法不正确):
TheProcessor()
{
MSG msg;
PeekMessage(&msg,...);
while(GetMessage(&msg...)
{ /* switch case here */ }
}
线程将调用PostThreadMessage - 有关详细信息,请参阅 MSDN。
当您需要发送超过 LPARAM/WPARAM 可以容纳的数据时,您最终需要在堆上分配它们,然后在自定义消息循环中处理消息后删除。这将是麻烦和错误的。
但是...我建议您在std::queue/deque 或其他DS 之上拥有自己的课程,您可以在其中添加AddMessage/PushMessage 和PopMessage(或任何您喜欢的名称) .您需要使用SetEvent、WaitForSingleObject 来触发循环中的新消息(请参阅implementation here 之一。您可以将其设为一种数据类型的通用类,或将其设为模板类——这将支持任何数据——类型(您的底层 DS (queue) 将使用相同的数据类型)。您也不必担心堆和删除。这不太容易出错。但是,您可能必须处理 MT 问题。
使用 Windows 事件涉及内核模式转换(因为事件是命名/内核对象),您可能希望使用作为用户对象的条件变量。或者您可以直接使用 VC10 中可用的并发运行时库中的unbounded_buffer 类。见this article(跳转到unbounded_buffer)。
【讨论】:
是的,您可以在工作线程上创建消息队列。您需要在该线程上运行消息泵。
【讨论】: