轉自:http://www.cnblogs.com/shootingstars/archive/2008/11/10/24602.html
線程函數:
DWORD WINAPI ThreadProc(
while(!bTerminate)
{
// 從一個鏈表中讀取資訊並且插入到CListCtrl中
// CListCtrl的控制代碼是通過線程參數傳遞進來的
for(;;)
{
ReadInfoFromList();
InsertToCListCtrl();
}
}
}s
主線程中使用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一類函數,而必須使用上述的方案。