在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)
下面的代碼我調試了將近一個星期,你能夠看出什么地方出了問題嗎?
線程函數:
??? 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, 0, 0, PM_REMOVE);
??????????? DispatchMessage(&msg);
??????? }
??? }
總結:
如果在工作線程中有可能涉及到了消息驅動的API,那么不能在主線程中使用 WaitForSingleObject一類函數,而必須使用上述的方案。
總結
以上是生活随笔為你收集整理的在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MED-V桌面虚拟化之二配置Templa
- 下一篇: 网络管理员&MCSE2003之12: 第