程序退出时使用WaitForSingleObject导致程序阻塞的原因及解决方法

程序退出时使用WaitForSingleObject导致程序阻塞的原因及解决方法

在程序退出时,我们通常都会使用WaitForSingleObject等函数等待指定的信号或等待线程析构。最近在开发程序时突然遇到了在析构函数中使用WaitForSingleObject等待线程结束时造成程序阻塞的情况。经过仔细分析发现是在线程执行过程中更新了界面资源,而(UI线程)主线程此时被WaitForSingleObject阻塞(消息循环机制被阻塞),导致界面资源得不到更新,造成死锁。

经过查找相关资料,发现可以使用MsgWaitForMultipleObjects或MsgWaitForMultipleObjectsEx替代WaitForSingleObject、MsgWaitForMultipleObjects等函数。

MsgWaitForMultipleObjects可以等待直到指定的一个或全部对象都在信号状态或超时间已到。这些对象可包括输入事件对象,可以用dwWakeMask参数指定。当有界面资源更新时使用PeekMessage处理消息,解决死锁问题。

代码如下:

DWORD dwWait;
do
{
    dwWait = MsgWaitForMultipleObjects(1, &m_dirWatch.m_pCalcThread->m_hThread, FALSE, 5000, QS_ALLINPUT); // wait five seconds
    switch (dwWait)
    {
    case WAIT_OBJECT_0:
        // handle became signalled!
        break;

    case WAIT_OBJECT_0 + 1:
        {
            // This thread awoke due to sent/posted message
            // process the message Q
            //
            // There is a message in this thread's queue, so 
            // MsgWaitForMultipleObjects returned.
            // Process those messages, and wait again.

            MSG msg;
            while(PeekMessage(&msg, NULL, 0,0, PM_REMOVE)) 
            {
                if( msg.message != WM_QUIT)
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else
                {
                    /****
                    This appears to be causing quite a lot of pain, to quote Mustafa.
                
                    // it's the WM_QUIT message, put it back in the Q and
                    // exit this function
                    PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam );
                    bWMQuitReceived = true;

                    ****/
                    break;
                }
            }
        }
        break;

    case WAIT_TIMEOUT:
        {
            TRACE(_T("WARNING: Possible Deadlock detected! ThreadID: %d File: %s Line: %d\n"), GetCurrentThreadId(), _T(__FILE__), __LINE__);
        }
        break;
    }//end switch(dwWait)
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值