下面的代碼我調試了將近一個(gè)星期
線(xiàn)程函數:
















當想終止子線(xiàn)程時(shí),在主線(xiàn)程中:
bTerminate = TRUE;
WaitForSingleObject(threadHandle, INFINITE);
可是,以運行到WaitForSingleObject,子線(xiàn)程就Crash了。
為什么呢?
問(wèn)題原因:
后來(lái)我終于在InsertItem的反匯編中發(fā)現了如下的代碼
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可見(jiàn),InsertItem是必須借助消息循環(huán)來(lái)完成任務(wù)的。如果我們在主線(xiàn)程中WaitForSingleObject了,必然導致主線(xiàn)程阻塞,也就導致了消息循環(huán)的阻塞,最終導致工作線(xiàn)程Crash掉了*_*
解決方案:
為了解決在主線(xiàn)程中Wait的問(wèn)題,微軟專(zhuān)門(mén)設計了一個(gè)函數MsgWaitForMultipleObjects,這個(gè)函數即可以等待信號(thread,event,mutex等等),也可以等待消息(MSG)。即不論有信號被激發(fā)或者有消息到來(lái),此函數都可以返回。呵呵,那么我的解決辦法也就出來(lái)了。
將上面的WaitForSingleObject用下面的代碼替換:

























總結:
如果在工作線(xiàn)程中有可能涉及到了消息驅動(dòng)的API,那么不能在主線(xiàn)程中使用WaitForSingleObject一類(lèi)函數,而必須使用上述的方案。


評論
謝謝你的文章!
回復 引用
回復 引用
作者你好,
消息循環(huán)只負責獲取消息隊列中的消息 ,
SendMessageA的消息并不進(jìn)入消息隊列
回復 引用
回復 引用
并沒(méi)有出現你說(shuō)的事情,線(xiàn)程依然很好干了他該干的事。我想可能是你搞錯了,導致死鎖了吧。
回復 引用
不知道你是如何做的測試,能夠把測試代碼貼出來(lái)嗎?
回復 引用 查看
SendMessageA發(fā)送的消息確實(shí)不進(jìn)入消息循環(huán),但是這個(gè)過(guò)程是在主線(xiàn)程的上下文中完成的,還是在開(kāi)的線(xiàn)程中完成的?
呵呵,有空再研究研究,或許原理還是有問(wèn)題。
回復 引用 查看
我是一個(gè)初學(xué)者,有VC高手希望能交個(gè)朋友。
我的E-MAIL:puma-ly@163.com
回復 引用
回復 引用
回復 引用
回復 引用
回復 引用
回復 引用
回復 引用
回復 引用
不過(guò)在WaitForSingleObject的第二個(gè)參數設置成一個(gè)數值也可以避免出問(wèn)題,不過(guò)沒(méi)有樓主的效果好~
回復 引用
回復 引用
你的主線(xiàn)程不是一個(gè)UI線(xiàn)程嗎?
我的建議是:在UI線(xiàn)程中等待某個(gè)事件發(fā)生一定使用MsgWaitForMultipleObjects,不要使用WaitForMultipleObjects。
回復 引用 查看
for沒(méi)辦法退出,怎么WaitForSingleObject?
回復 引用
在debug版本下面正常運行
但如果在release版本下,你的等待那個(gè)函數
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);
}
}
好像就沒(méi)起作用了。
我估計是不是函數的返回值有問(wèn)題。。。不太清楚,希望你能幫忙看下,
謝謝??!
回復 引用
回復 引用
1. 的線(xiàn)程代碼中的 for(;;){
ReadInfoFromList();
InsertToCListCtrl();
}
好像沒(méi)有必要要for(;;){}這一層吧,這樣的話(huà)你的while(!bTerminate)就沒(méi)有什么意義了,永遠沒(méi)法執行到吧,
2. result = MsgWaitForMultipleObjects(1, &readThreadHandle, FALSE, INFINITE, QS_ALLINPUT); 如果你用INFINITE永遠等待不超時(shí)后面的代碼在在等待的時(shí)間沒(méi)有發(fā)生的情況下還能執行到嗎?
回復 引用
回復 引用 查看
回答你
1,人家那是簡(jiǎn)寫(xiě)。難道樓主故意寫(xiě)個(gè)死循環(huán)在那么?
2,你根本就沒(méi)看懂。人家說(shuō)是有消息來(lái)也可以往下執行。知道什么是有消息么?
回復 引用
CListCtrl 只能在主線(xiàn)程操作。
WaitForSingleObject 沒(méi)問(wèn)題。
回復 引用