最近做了个监控程序,除主线程外另外开了一个线程来更新界面控件listctrl,当程序正在运行时为了避免突然中止正在运行的线程造成的资源没有释放问题,我在OnDestory中等待线程退出,这样造成了主线程等待辅助线程结束,而辅助线程由于主线程的循环等待而无法更新界面这样的死锁情况,经过查询资料和大家的帮助,我知道用MsgWaitForMultipleObjects可以解决这种等待线程结束的同时也能接收消息的情况,感觉挺好,下面是我的OnDestory和子线程
void CDataManger::OnDestroy()
{
CFormView::OnDestroy();
pDataManger->v_bDestory=true;
bool v_bWait=true;
while(v_bWait)
{
DWORD dwEvt=MsgWaitForMultipleObjects( 1 , & pDataManger->m_hThumbnailThread->m_hThread,FALSE,50,QS_ALLINPUT);

switch (dwEvt) 
{
case  WAIT_OBJECT_0:
v_bWait= false ;
break ; case  WAIT_OBJECT_0  +   1 :        
{
MSG msg;
PeekMessage( & msg, NULL,  0 ,  0 , PM_REMOVE);
TranslateMessage( & msg);
DispatchMessage( & msg);
break ;
}  default :   //  WAIT_TIMEOUT  WAIT_FAILED 
break ;

}
theApp.v_pFrame[4]=NULL;    //表明该文档框架还未创建
theApp.a_bPower[6]=true;    //菜单有效
}子线程:
UINT CDataManger::ProDrawThumbnails(LPVOID lparame)
{
CDataManger* pdg=(CDataManger*)lparame;
while(true)
{
if (pdg->Thumbnaillist.IsEmpty()&&!pdg->v_bDestory) //链表为空且未点击关闭按钮
{
Sleep(50);
continue;
}
else if(!pdg->v_bDestory)             //尚未点击关闭按钮
{
更新listctrl
}
else
{
释放资源
             pdg->v_bEndThread=true; //设置线程退出标志以通知OnDestory
}
}
return 0;
}我在几台电脑上测试没有问题,但是放到性能较高的服务器上测试会卡死在MsgWaitForMultipleObjects,或者过很长一段时间才会真正退出(因为每次退出时更新文档创建标志theApp.v_pFrame[4]以便再次响应菜单创建新文档,现在再次点击菜单不会反应,知道真正退出时才有反应),为什么呢?求指点

解决方案 »

  1.   

    先不看你的代码和问题了,单是你前面的描述我就没看明白。既然主线程已经进入 OnDestroy() 了,也就是主窗口已经在屏幕上消失了,那么还有什么需要“更新界面”呢?如果你的辅助线程是一个 UI 线程,那它会有自己的消息循环,不受主线程的影响,仍然能够更新自己所拥有的界面窗口。所以……哪里来的死锁?
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)