終止進程
終止進程會產生下列結果:
- 進程中的任何剩餘執行緒都會標示為終止。
- 釋放進程所配置的任何資源。
- 所有核心物件都會關閉。
- 進程程式碼會從記憶體中移除。
- 已設定進程結束代碼。
- 進程物件會發出訊號。
當進程終止時,當核心物件的開啟控制碼自動關閉時,物件本身會存在,直到關閉所有開啟的控制碼為止。 因此,如果另一個進程有開啟的控制碼,物件就會在使用該物件的進程終止之後保持有效。
GetExitCodeProcess函式會傳回進程的終止狀態。 當進程正在執行時,其終止狀態會STILL_ACTIVE。 當進程終止時,其終止狀態會從STILL_ACTIVE變更為進程的結束代碼。
當進程終止時,進程物件的狀態會變成訊號,釋放任何等候進程終止的執行緒。 如需同步處理的詳細資訊,請參閱 同步處理多個執行緒的執行。
當系統終止進程時,它不會終止進程所建立的任何子進程。 終止進程不會產生WH_CBT攔截程式的通知。
使用 SetProcessShutdownParameters 函式來指定在系統關機時終止進程的某些層面,例如當進程應該相對於系統中的其他進程終止時。
進程終止的方式
進程會執行,直到發生下列其中一個事件為止:
- 進程的任何執行緒都會呼叫 ExitProcess 函式。 請注意,如果進程的主要執行緒傳回,C 執行時間程式庫的某些實作 (CRT) 呼叫 ExitProcess 。
- 進程的最後一個執行緒會終止。
- 任何執行緒都會使用進程的控制碼呼叫 TerminateProcess 函式。
- 針對主控台進程,當主控台收到 CTRL+C 或 CTRL+BREAK 訊號時,預設 主控台控制項處理常式 會呼叫 ExitProcess 。
- 使用者關閉系統或登出。
除非執行緒處於已知狀態,否則請勿終止進程。 如果執行緒正在等候核心物件,在等候完成之前將不會終止。 這可能會導致應用程式停止回應。
主要執行緒可以避免終止其他執行緒,方法是指示它們呼叫 ExitThread ,再造成進程終止 (以取得詳細資訊,請參閱 終止執行緒) 。 主要執行緒之後仍然可以呼叫 ExitProcess ,以確保所有線程都已終止。
進程的結束代碼是呼叫 ExitProcess 或 TerminateProcess中指定的值,或是進程之 main 或 WinMain 函 式所傳回的值。 如果因嚴重例外狀況而終止進程,結束代碼就是造成終止的例外狀況值。 此外,此值會當做發生例外狀況時所執行之所有線程的結束代碼使用。
如果 ExitProcess終止進程,系統會使用值呼叫每個附加 DLL 的進入點函式,指出進程與 DLL 中斷連結。 當 TerminateProcess終止進程時,DLL 不會收到通知。 如需 DLL 的詳細資訊,請參閱 動態連結程式庫。
如果進程由 TerminateProcess終止,進程的所有線程都會立即終止,而且沒有機會執行其他程式碼。 這表示執行緒不會在終止處理常式區塊中執行程式碼。 此外,不會收到任何附加 DLL 的通知,表示進程正在中斷連結。 如果您需要讓某個進程終止另一個進程,下列步驟會提供更好的解決方案:
讓這兩個進程呼叫 RegisterWindowMessage 函式來建立私人訊息。
其中一個進程可以使用 BroadcastSystemMessage 函式來廣播私人訊息,以終止另一個進程,如下所示:
DWORD dwRecipients = BSM_APPLICATIONS; UINT uMessage = PM_MYMSG; WPARAM wParam = 0; LPARAM lParam = 0; BroadcastSystemMessage( BSF_IGNORECURRENTTASK, // do not send message to this process &dwRecipients, // broadcast only to applications uMessage, // registered private message wParam, // message-specific value lParam ); // message-specific value
接收私人訊息的進程會呼叫 ExitProcess 來終止其執行。
ExitProcess、ExitThread、CreateThread、CreateRemoteThread和CreateProcess函式的執行會在位址空間內序列化。 適用以下限制:
- 在進程啟動和 DLL 初始化常式期間,可以建立新的執行緒,但除非進程完成 DLL 初始化,否則不會開始執行。
- 一次只能有一個執行緒位於 DLL 初始化或卸離常式中。
- 在 DLL 初始化或卸離常式中沒有線程之前, ExitProcess 函式不會傳回。