工作執行緒操作主介面控制元件引起死鎖及解決
問題描述:
在監控程式中,設計一監控迴圈。
標頭檔案 .h
HANDLE m_hEventExit;
CWinThread* m_pThread;
建構函式中,建立該事件
m_hEventExit=CreateEvent(NULL, // 安全
TRUE, // 手動
FALSE, // 初始化為非訊號模式
_T("Exit Event") // 執行緒名稱
);
在 OnButtonThreadStart() 中
{
if(!m_pThread)
{
ResetEvent(m_hEventExit);
m_ pThread = AfxBeginThread(MonitorThreadFunc, this);
}
}
MonitorThreadFunc 中需要修改主介面中的控制元件。
這時候如果在 OnButtonThreadStop ()中
{
SetEvent(m_hEventExit);
if(m_ pThread!= NULL)
{
TRACE0("The thread is still running.\n");
WaitForSingleObject(m_ pThread ->m_hThread, -1);
delete m_ pThread;
m_ pThread = NULL;
}
}
其中 Wait 行使主介面進入等待狀態,如果這時候工作執行緒執行完了,可以順利退出,如果執行緒此時正在更新介面控制元件,就會陷入死鎖。
解決方法:
使用 WaitThreadWithHandleMsg 函式,可以在等待執行緒結束的同時響應訊息。
為了使用方便,將該函式封裝了一下,使用的時候只需要呼叫一下。
int WINAPI WaitThreadWithHandleMsg(HANDLE hEventThread){
HRESULT hResult = S_FALSE;
BOOL bWait = TRUE;
while (bWait)
{
DWORD dwEvt = MsgWaitForMultipleObjects( 1 , & hEventThread,FALSE,INFINITE,QS_ALLINPUT);
switch (dwEvt)
{
case WAIT_OBJECT_0:
bWait = false ;
hResult = TRUE;
break ;
case WAIT_OBJECT_0 + 1 :
{
MSG msg;
while (::PeekMessage( & msg, NULL, 0 , 0 , PM_NOREMOVE))
{
if (WM_CLOSE == msg.message || WM_QUIT == msg.message)
{
bWait = false ;
break ;
}
else
{
PeekMessage( & msg, NULL, 0 , 0 , PM_REMOVE);
TranslateMessage( & msg);
DispatchMessage( & msg);
}
}
break ;
}
default : // WAIT_TIMEOUT WAIT_FAILED
bWait = false ;
hResult = FALSE;
break ;
}
} // end while
return hResult;
} From:http://www.cppblog.com/sleepwom/archive/2009/02/13/73688.html