- ...
- m_hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- ...
- while (TRUE)
- {
- // 等待
- ::WaitForSingleObject(pThis->m_hEvent, INFINITE);
- if (pThis->GetStop())
- {
- // 取消
- break;
- }
- pThis->StartWork(TRUE);
- }
- ...
- m_bstop = TRUE;
- ::SetEvent(m_hEvent);
- ...
分享一點關於線程安全退出的東東:
前因:工作線程不是總處於working狀態,大部分時間可能處於等待狀態,收到“取消”的消息后怎么退出;
方法:使用bool stop標識,當stop為true的時候退出,但是線程在WaitForSingleObject的時候必須激活該線程,所以還需要一個事件來激活它,之前我用了一個自動重置的event,后來發現自動重置的event偶爾會丟失激活事件,譬如說,線程進入pThis->StartWork(TRUE);之后,外面來了一個取消事件激活了事件,但是線程再次走到WaitForSingleObject的時候卻不會等到該事件,該事件被系統拋棄了(具體來說就是激活一個自動重置的事件時,系統中並沒有一個wait族函數等待該事件,這個狀態不會被系統保存下來,換句話說,這個event的該次激活被遺失了,具體是指PulseEvent激活的,SetEvent激活的還沒發現問題);
解決方法:使用手動重置的event,另外建議不要無窮等待,代碼如下:
- ...
- m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- ...
- while (TRUE)
- {
- // 等待
- if (WAIT_TIMEOUT == ::WaitForSingleObject(pThis->m_hEvent, 200))
- {
- if (pThis->GetStop())
- {
- // 取消
- break;
- }
- continue;
- }
- ::ResetEvent(pThis->m_hEvent);
- if (pThis->GetStop())
- {
- // 取消
- break;
- }
- pThis->StartWork(TRUE);
- }
- ...
- m_bstop = TRUE;
- ::SetEvent(m_hEvent);
- ...
下面是來之zeno的分享::-)
跟大家分享一個多線程編程的BUG經驗:
場景:
A.線程正在運行,且線程函數會調用UI類中的會更新界面的成員函數
B.在UI類的按鈕消息函數中停止線程運行。
結果:線程在調用UI類中的會更新界面的成員函數會CRASH。
原因:“UI類的按鈕消息函數中停止線程運行” 與 “UI類中的會更新界面的成員函數”同在UI線程的消息循環中,會引起死鎖,這種情況下,一些等待函數(如WaitForSingleObject)會超時,導致某一方的代碼調不到,從而導致異常邏輯,CRASH就發生了。
建議解決方案:避免“UI類的按鈕消息函數中停止線程運行” 與 “UI類中的會更新界面的成員函數”發生死鎖,避免的方法很多了,各自在具體編程時可自行決定(如使用標識變量等)
http://blog.csdn.net/magictong/article/details/4041696