工作线程操作主界面控件引起死锁及解决

问题描述:

在监控程序中,设计一监控循环。

头文件 .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

你可能感兴趣的:(windows,C++)