前言:多線程
近日在網上看到不少人問及如何關閉一下線程,可是我看網上給出的並不詳細,並且有些方法仍是錯誤的。小弟在此拙做一篇,不談別的,只談及如何正確的關閉MFC的線程,至於Win32和C RunTime的線程暫不涉及。函數
一.關於MFC的線程oop
1.MFC的線程有兩種,一種稱爲Work線程,一種稱爲UI線程。通常狀況下Work線程與UI線程的區別主要在於UI線程有消息隊列(並非有沒有界面,這點要注意,UI線程也是能夠沒有界面的)。ui
2.建立這兩種線程的區別也不大,能夠從建立函數看出。線程
關於函數的具體使用,請查閱MSDN,這裏不涉及。設計
二. 結束線程前的注意事項對象
在結束一個線程前,只有一點要注意,那就是m_bAutoDelete 的狀態。(什麼?不知道m_bAutoDelete ?!!快去查閱MSDN吧)。隊列
m_bAutoDelete = TRUE; 系統本身清理CWind對象,固然還包括CloseHandle(),ExitInstance()等等一堆函數的調用。內存
m_bAutoDelete = FALSE; 那麼就必定要記得本身在用完後調用delete刪除建立線程的對象,這一點極爲重要,由於不調用delete必定會有內存泄漏問題。消息隊列
總之m_bAutoDelete 的值對結束工做是很重要的,這點必定要注意。
三.正確的結束一個Work線程
由於Work線程是一個全局函數,或者是一個Static函數,因此它的運行完成也就是它的正常退出了。(什麼?不明白,示例代碼以下)
1.狀況一:
2.狀況二:
Work線程是個死循環或一時半會兒出不來,這時要主線程要發個消息給Work線程,讓他退出。
關於主線程發一個激發態的消息給Work線程,有多種方法,如在主線程裏調用SetEvent()等等,你想用什麼都行,可是最好不要在Work線程裏用Busy loop的方法。至於爲何,請參閱《Win32多線程程序設計》上面的論述。
四.正確結束一個UI線程
由於UI線程有消息隊列,因此結束一個UI線程最好的方法是發一個WM_QUIT消息給消息隊列,方法不少如:PostQuitMessage(),PostThreadMessage()等等。可是發出消息後最好等待看UI線程是否已經退出(不少人都沒有說起這一點,可是實際工做中發現,加上這一點是多麼的重要)。
五.關於幾個問題的解答
1.問:爲何個人UI線程沒有調用ExitInstance()?
答:最大的多是你的WM_QUIT消息沒有通知到UI線程。爲了保險期間最好調用PostThreadMessage(),這樣能夠指定線程的ID。固然若是你對消息比較熟悉的話,也能夠拋一個消息到最頂層。
2.問:爲何個人UI線程沒有調用析構函數?
答:檢查看你的m_bAutoDelete = FALSE,若是是的話,那麼看你的線程對象是否已經delete了。通常狀況下調用delete會調用析構函數。
3.問:在UI線程中沒有調用WaitForSingleObject(),會怎麼樣?
答:咱們知道在PostMessage()以後,函數會立刻返回,如查沒有wait...(),那麼緊接着就調用了delete,頗有可能對象作的退出操做過程尚未完成時,又把對象delete掉了,結果仍是沒有正常結束。(注:WM_QUIT消息以後會觸發一堆函數,這個時間是不定的,因此最好Wait...纔是正道。)
六.最後不肯提的函數
幾乎每本講線程的書都會提到下面的函數:
void AfxEndThread(UINT nExitCode);
TerminateThread();
......還有其它的一些極端的函數
個人觀點是:最好不要使用,除非你知道要發生什麼!!