【发布时间】:2021-03-17 02:15:37
【问题描述】:
我有一个主线程,它会根据用户从主 UI 中选择的内容触发其他几个线程来完成各种工作。通常我会使用 WaitForMultipleObjects() 并将 bWaitAll 设置为 TRUE。但是,在这种情况下,那些其他线程会将输出记录到另一个窗口,该窗口使用互斥锁来确保线程一次只输出一个。该过程的一部分使用SendMessage() 发送获取文本大小并将文本发送到如果使用WaitForMultipleObjects() 将挂起的窗口,因为它是从主UI 线程运行的。所以我转而使用 MsgWaitForMultipleObjects 和 QS_SENDMESSAGE 标志,唯一的问题是 bWaitAll 的逻辑,它指出只有在所有对象都发出信号 AND 时才会返回输入事件发生(而不是在所有对象都收到信号或输入事件发生时返回)。如果逻辑是OR,这应该可行:
DWORD waitres=WAIT_FAILED;
while (1)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
// mfc message pump
if (!theApp.PumpMessage()) {
// program end request
// TO DO
}
}
// MFC idel processing
LONG lidlecount = 0;
while (theApp.OnIdle(lidlecount++));
// our wait
waitres = ::MsgWaitForMultipleObjects(threadcount, threadhandles, TRUE, INFINITE, QS_SENDMESSAGE);
// check if ended due to message
if (waitres!=WAIT_OBJECT_0+threadcount) {
// no, exit loop
break;
}
}
与其触发一个线程然后触发其他线程,我想知道从主线程处理这个问题的正确方法是什么?我考虑过使用 bWaitAll FALSE 然后使用 WaitForMultipleObjects() 并将 bWaitAll 设置为 TRUE 并将 dwMilliseconds 设置为 0(或 1)并检查结果看是否完成。如果没有,它需要循环回到循环的顶部,然后循环到MsgWaitForMultipleObjects(),当使用 bWaitAll FALSE 时,如果多个线程之一完成(比如 10 个线程中的 1 个线程),它可能会立即返回完成,我可以如上所述检查是否全部完成,但是当返回 bWaitAll FALSE 时它只会返回而不是等待)。
那么在 MFC 应用程序的主线程中处理等待多个线程(使用 SendMessage())完成的正确方法是什么?
谢谢。
【问题讨论】:
-
使用
MsgWaitForMultipleObjects()和bWaitAll=FALSE是正确的解决方案。将线程句柄放入数组中,每次等待指示线程完成时,从数组中删除该线程。继续循环直到数组为空。只要等待指示有待处理的消息,就抽出消息队列。 -
一般来说 - 是的,您永远不必将 bWaitAll 设置为 TRUE。使用
bWaitAll=FALSE并根据需要更改等待数组。万一线程/进程 - 当然在它发出信号后从数组中删除句柄。但对于具体任务 - 所有解决方案都是错误的。你不需要等待线程句柄。您需要为具有引用计数的任务创建通用结构。当线程退出时 - 它释放引用计数。当结构被破坏(不再有线程)向您的窗口发布消息时