在一个C ++应用程序中,我有一个窗口,其消息循环在单独的线程中运行,因为主线程正忙于计算和渲染模拟。 该窗口充当仿真的日志窗口。 当模拟引发exception时,仿真closures,日志窗口显示细节。
现在主线程应该等到日志窗口closures。 由于消息循环运行在一个单独的线程,我试图
WaitForSingleObject(logwindow->thread, INFINITE);
从主线程。
但是,这似乎阻止了消息泵和日志窗口冻结。 那么我该如何正确地等待,直到一个窗口closures或线程结束?
ED:窗口是在主线程上创build的,但运行在不同的线程上。 我将继续并改变它,以便它也在消息循环线程上创build。
你有几个选择。
PostMessage或SendMessage 。 MsgWaitForMultipleObjects等待。 为了详细说明MsgWaitForMultipleObjects ,它是一个等待函数,可以配置为当消息到达队列时返回。 因此,您可以保持消息泵处于活动状态,同时在处理排队的消息之间使用阻塞等待。
在伪代码中,你可以这样写:
do { WaitResult = MsgWaitForMultipleObjects(1, hThread, TRUE, INFINITE, QS_ALLEVENTS); if (WaitResult == MessageArrivedOnQueue) PumpMessageQueue(); } while (WaitResult != WaitHandlesSignaled)
事实上,当主线程处于阻塞等待状态时,日志窗口处于冻结状态,这表明工作线程正在向主线程发送消息,然后等待回复,但主线程已经被阻塞,无法回复。 这是两个线程经典的死锁情况。 您应该在主线程中使用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工作,并在工作线程中进行计算,而不是相反。