天天看點

主線程中慎用WaitForSingleObject (WaitForMultipleObjects)主線程中慎用WaitForSingleObject (WaitForMultipleObjects)

主線程中慎用WaitForSingleObject (WaitForMultipleObjects)

下面的代碼我調試了将近一個星期,你能夠看出什麼地方出了問題嗎?

線程函數:

 DWORD WINAPI ThreadProc(

    while(!bTerminate)

    {

        // 從一個連結清單中讀取資訊并且插入到CListCtrl中

        // CListCtrl的句柄是通過線程參數傳遞進來的

        for(;;)

       {

           ReadInfoFromList();

           InsertToCListCtrl();

        }

    }

}

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

當想終止子線程時,在主線程中:

bTerminate = TRUE;

WaitForSingleObject(threadHandle, INFINITE);

可是,一運作到WaitForSingleObject,子線程就Crash了。

為什麼呢?

後來我終于在InsertItem的反彙編中發現了如下的代碼:

call dword ptr [[email protected] (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, 0, 0, PM_REMOVE);

        DispatchMessage(&msg);

    }

}

總結:

如果在工作線程中有可能涉及到了消息驅動的API,那麼不能在主線程中使用WaitForSingleObject一類函數,而必須使用上述的方案。

【轉載】https://www.cnblogs.com/shootingstars/archive/2004/07/15/24602.html

繼續閱讀