欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)

发布时间:2025/6/15 编程问答 35 豆豆
生活随笔 收集整理的这篇文章主要介绍了 在主线程中慎用WaitForSingleObject (WaitForMultipleObjects) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

下面的代码我调试了将近一个星期,你能够看出什么地方出了问题吗?

线程函数:
    DWORD WINAPI ThreadProc()
    {
        while(!bTerminate)
        {
            // 从一个链表中读取信息并且插入到CListCtrl中
            // CListCtrl的句柄是通过线程参数传递进来的
            for(;;)
            {
               ReadInfoFromList();
               InsertToCListCtrl();
            }
        }
    }


主线程中使用CreateThread 启动线程。

当想终止子线程时,在主线程中:
    bTerminate = TRUE;
    WaitForSingleObject(threadHandle, INFINITE);
可是,以运行到WaitForSingleObject,子线程就Crash了。

问题原因:
后来我终于在InsertItem的反汇编中发现了如下的代码
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了*_*

解决方案:
为了解决在主线程中Wait的问题,微软专门设计了一个函数MsgWaitForMultipleObjects,这个函数即可以等待信号(thread,event,mutex等等),也可以等待消息(MSG)。即不论有信号被激发或者有消息到来,此函数都可以返回。呵呵,那么我的解决办法也就出来了。
将上面的WaitForSingleObject用下面的代码替换:
    while(TRUE)
    {
    
        DWORD result ;
        MSG msg ;
    
        result = MsgWaitForMultipleObjects(1, &readThreadHandle,
            FALSE, INFINITE, QS_ALLINPUT);
    
        if (result == (WAIT_OBJECT_0))
        {
            break;
        }
        else
        {
            PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
            DispatchMessage(&msg);
        }
    }



总结:
如果在工作线程中有可能涉及到了消息驱动的API,那么不能在主线程中使用 WaitForSingleObject一类函数,而必须使用上述的方案。

总结

以上是生活随笔为你收集整理的在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。