为什么 win32 消息循环在线程化时停止工作?
Why does the win32 message loop stop working when threaded?
我正在尝试创建一个 WIN32 (C++) 程序,我必须在其中同时处理消息和 运行 一个 while 循环。为此,我想使用线程。
当我将消息循环移动到一个单独的过程(从函数 WinMain 调用)时,一切正常。但是,当我使用下面的代码线程化该过程时,而不是简单地从主进程调用它时,window 变得没有响应。
你知道为什么会这样吗?
在 WinMain 中,在创建主 window 之后,我删除了消息循环和 return 值,添加了以下代码:
std::thread t1(message_loop);
t1.join();
return return_val;
return_val
是一个全局变量,当消息循环结束时,我将使用它来接收 WinMain 应该 return 的值。
另外,函数message_loop如下:
void message_loop()
{
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
return_val = messages.wParam;
}
根本原因是Windows有线程消息队列的概念。每个线程都有自己的消息队列。在线程中 运行 GetMessage
没问题,但它只会让您获得属于该线程的消息,例如您在该线程中创建的 windows 。属于任何其他线程的消息(无论该其他线程是如何创建的)在您的线程中将不可见。
如您所述,您的 std::thread
仅在“创建主要 window 之后”创建。这意味着您有两个线程消息队列;一个来自创建主线程 window 的主线程,另一个队列用于您的 std::thread
。后一个队列将保持为空。
您在 GetMessage
的第二个参数中看到了这一点 - 传递 HWND=0
意味着“该线程的所有消息”。
理论上,您可以为多个 windows 使用多个线程,但这很快就会变得非常复杂。所以在实践中,最常见的解决方案是使用 main
线程,唯一合理的选择是拥有一个专用线程。
我正在尝试创建一个 WIN32 (C++) 程序,我必须在其中同时处理消息和 运行 一个 while 循环。为此,我想使用线程。
当我将消息循环移动到一个单独的过程(从函数 WinMain 调用)时,一切正常。但是,当我使用下面的代码线程化该过程时,而不是简单地从主进程调用它时,window 变得没有响应。
你知道为什么会这样吗?
在 WinMain 中,在创建主 window 之后,我删除了消息循环和 return 值,添加了以下代码:
std::thread t1(message_loop);
t1.join();
return return_val;
return_val
是一个全局变量,当消息循环结束时,我将使用它来接收 WinMain 应该 return 的值。
另外,函数message_loop如下:
void message_loop()
{
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
return_val = messages.wParam;
}
根本原因是Windows有线程消息队列的概念。每个线程都有自己的消息队列。在线程中 运行 GetMessage
没问题,但它只会让您获得属于该线程的消息,例如您在该线程中创建的 windows 。属于任何其他线程的消息(无论该其他线程是如何创建的)在您的线程中将不可见。
如您所述,您的 std::thread
仅在“创建主要 window 之后”创建。这意味着您有两个线程消息队列;一个来自创建主线程 window 的主线程,另一个队列用于您的 std::thread
。后一个队列将保持为空。
您在 GetMessage
的第二个参数中看到了这一点 - 传递 HWND=0
意味着“该线程的所有消息”。
理论上,您可以为多个 windows 使用多个线程,但这很快就会变得非常复杂。所以在实践中,最常见的解决方案是使用 main
线程,唯一合理的选择是拥有一个专用线程。