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

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

问题描述:

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

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

 

你可能感兴趣的:(工作线程操作主界面控件引起死锁及解决)