1. 程式人生 > >工作執行緒操作主介面控制元件引起死鎖及解決

工作執行緒操作主介面控制元件引起死鎖及解決

問題描述:

在監控程式中,設計一監控迴圈。

標頭檔案 .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