等到窗口关闭时,消息循环在另一个线程上

时间:2011-07-29 20:01:19

标签: c++ windows multithreading

在一个C ++应用程序中,我有一个窗口,其消息循环在一个单独的线程中运行,因为主线程忙于计算和渲染模拟。该窗口充当模拟的日志窗口。当模拟抛出异常时,模拟将关闭,日志窗口将显示详细信息。

现在主线程应该等到日志窗口关闭。由于消息循环在一个单独的线程上运行,我试图

WaitForSingleObject(logwindow->thread, INFINITE);

来自主线程。

然而,这似乎阻止了消息泵和日志窗口冻结。那么如何才能正确等待窗口关闭或线程结束?

ED:窗口在主线程上创建,但在不同的线程上运行。我将继续进行更改,以便在消息循环线程中创建它。

2 个答案:

答案 0 :(得分:2)

您有几个选择。

  1. 从主线程中运行所有UI并获取工作线程以将报告同步回主线程以显示,例如通过PostMessageSendMessage
  2. 当工作完成后,不要等待并让工作线程向主线程发布消息。
  3. 使用MsgWaitForMultipleObjects等待。
  4. 详细说明MsgWaitForMultipleObjects,它是一个等待函数,可以配置为在消息到达队列时返回。因此,您可以保持消息泵处于活动状态,同时在处理排队消息之间使用阻塞等待。

    在伪代码中你会这样写:

    do
    {    
        WaitResult = MsgWaitForMultipleObjects(1, hThread, TRUE, INFINITE, QS_ALLEVENTS);
        if (WaitResult == MessageArrivedOnQueue) 
            PumpMessageQueue();
    } while (WaitResult != WaitHandlesSignaled)
    

答案 1 :(得分:0)

当主线程处于阻塞等待时,日志窗口冻结这一事实表明工作线程正在向主线程发送消息然后等待回复,但主线程已被阻止且无法回复它。这是两个线程的典型死锁情况。您应该在主线程中使用MsgWaitForMultipleObjects()而不是WaitForSingleObject()来检测新消息在等待时何时需要处理,例如:

do
{
    DWORD dwRet = MsgWaitForMultipleObjects(1, &(logwindow->thread), FALSE, INFINITE, QS_ALLINPUT);
    if (dwRet == 0xFFFFFFFF) break;
    if (dwRet == (WAIT_OBJECT_0 + 1))
    {
      process messages here...
    }
}
while (dwRet != WAIT_OBJECT_0);

我同意David的观点,你真的应该在主线程中完成所有UI工作并在工作线程中进行计算,而不是相反。