多執行緒:MFC 中的終止執行緒
兩個正常情況導致執行緒終止:控制函式結束或不允許執行緒執行完成。 如果文字處理器使用執行緒進行背景列印,控制函式會在列印順利完成時正常終止。 不過,如果使用者想要取消列印,背景列印執行緒必須提前終止。 本主題說明如何實作每個情況,以及如何線上程終止之後取得執行緒的結束代碼。
一般執行緒終止
針對背景工作執行緒,一般執行緒終止很簡單:結束控制函式並傳回值,表示終止的原因。 您可以使用 AfxEndThread 函式或 return
語句。 一般而言,0 表示成功完成,但這是由您決定的。
針對使用者介面執行緒,程式同樣簡單:從使用者介面執行緒中呼叫 Windows SDK 中的 PostQuitMessage 。 唯 PostQuitMessage
一採用的參數是執行緒的結束代碼。 至於背景工作執行緒,0 通常表示成功完成。
過早執行緒終止
過早終止執行緒幾乎很簡單:從執行緒內呼叫 AfxEndThread 。 傳遞所需的結束代碼作為唯一的參數。 這會停止執行緒的執行、解除配置執行緒的堆疊、中斷連結至執行緒的所有 DLL,以及從記憶體中刪除線程物件。
AfxEndThread
必須從執行緒內呼叫,才能終止。 如果您想要從另一個執行緒終止執行緒,您必須設定兩個執行緒之間的通訊方法。
擷取執行緒的結束代碼
若要取得背景工作角色或使用者介面執行緒的結束代碼,請呼叫 GetExitCodeThread 函式。 如需此函式的相關資訊,請參閱 Windows SDK。 此函式會接受執行緒的控制碼(儲存在 m_hThread
物件的資料成員 CWinThread
中),以及 DWORD 的位址。
如果執行緒仍在使用中, GetExitCodeThread
請將STILL_ACTIVE放在提供的 DWORD 位址中;否則,結束代碼會放在這個位址中。
擷取 CWinThread 物件的結束代碼 需要額外的步驟。 根據預設,當 CWinThread
執行緒終止時,會刪除線程物件。 這表示您無法存取資料成員, m_hThread
CWinThread
因為物件已不存在。 若要避免這種情況,請執行下列其中一項動作:
將資料
m_bAutoDelete
成員設定為 FALSE。 這可讓CWinThread
物件在終止執行緒之後生存。 接著,您可以線上程終止之後存取m_hThread
資料成員。 不過,如果您使用這項技術,您必須負責終結CWinThread
物件,因為架構不會自動為您刪除它。 這是慣用的方法。分別儲存執行緒的控制碼。 建立執行緒之後,將其資料成員 (using
::DuplicateHandle
) 複製到m_hThread
另一個變數,並透過該變數加以存取。 如此一來,當終止發生時,物件會自動刪除,您仍然可以找出執行緒終止的原因。 請小心執行緒不會終止,才能複製控制碼。 若要這樣做,最安全的方式是將CREATE_SUSPENDED傳遞至 AfxBeginThread、儲存控制碼,然後藉由呼叫 ResumeThread 繼續執行緒。
任一 CWinThread
種方法都可讓您判斷物件終止的原因。
另請參閱
使用 C++ 和 MFC 進行多執行緒處理
_endthread、_endthreadex
_beginthread、_beginthreadex
ExitThread