主線程裏面使用WaitForSingleObject (WaitForMultipleObjects)須要考慮的狀況(轉)

下面的代碼可以看出什麼地方出了問題嗎?

線程函數:
web

  DWORD WINAPI ThreadProc(
    
  while   (   !   bTerminate)
    
  {
        
 //  從一個鏈表中讀取信息而且插入到CListCtrl中
        
 //  CListCtrl的句柄是經過線程參數傳遞進來的 
 
         for (;;)
       
 {
           ReadInfoFromList();
           InsertToCListCtrl();
        }
 

    }
 

}

主線程中使用CreateThread啓動線程。

當想終止子線程時,在主線程中:
bTerminate = TRUE;
WaitForSingleObject(threadHandle, INFINITE);
但是,以運行到WaitForSingleObject,子線程就Crash了。

爲何呢?

問題緣由:
後來我終於在InsertItem的反彙編中發現了以下的代碼
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可見,InsertItem是必須藉助消息循環來完成任務的。若是咱們在主線程中WaitForSingleObject了,必然致使主線程阻塞,也就致使了消息循環的阻塞,最終致使工做線程Crash掉了*_*

解決方案:
爲了解決在主線程中Wait的問題,微軟專門設計了一個函數MsgWaitForMultipleObjects,這個函數便可以等待信號(thread,event,mutex等等),也能夠等待消息(MSG)。即不論有信號被激發或者有消息到來,此函數均可以返回。呵呵,那麼個人解決辦法也就出來了。
將上面的WaitForSingleObject用下面的代碼替換:函數

while (TRUE)
{

    DWORD result ; 
    MSG msg ; 

    result 
= MsgWaitForMultipleObjects(1&readThreadHandle, 
        FALSE, INFINITE, QS_ALLINPUT); 

    
if (result == (WAIT_OBJECT_0))
    
{
        
break;
    }
 
    
else 
    

        PeekMessage(
&msg, NULL, 00, PM_REMOVE);
        DispatchMessage(
&msg); 
    }
 
}


總結:
若是在工做線程中有可能涉及到了消息驅動的API,那麼不能在主線程中使用WaitForSingleObject一類函數,而必須使用上述的方案。this

相關文章
相關標籤/搜索