終止進程

終止進程會產生下列結果:

  • 進程中的任何剩餘執行緒都會標示為終止。
  • 釋放進程所配置的任何資源。
  • 所有核心物件都會關閉。
  • 進程程式碼會從記憶體中移除。
  • 已設定進程結束代碼。
  • 進程物件會發出訊號。

當進程終止時,當核心物件的開啟控制碼自動關閉時,物件本身會存在,直到關閉所有開啟的控制碼為止。 因此,如果另一個進程有開啟的控制碼,物件就會在使用該物件的進程終止之後保持有效。

GetExitCodeProcess函式會傳回進程的終止狀態。 當進程正在執行時,其終止狀態會STILL_ACTIVE。 當進程終止時,其終止狀態會從STILL_ACTIVE變更為進程的結束代碼。

當進程終止時,進程物件的狀態會變成訊號,釋放任何等候進程終止的執行緒。 如需同步處理的詳細資訊,請參閱 同步處理多個執行緒的執行

當系統終止進程時,它不會終止進程所建立的任何子進程。 終止進程不會產生WH_CBT攔截程式的通知。

使用 SetProcessShutdownParameters 函式來指定在系統關機時終止進程的某些層面,例如當進程應該相對於系統中的其他進程終止時。

進程終止的方式

進程會執行,直到發生下列其中一個事件為止:

  • 進程的任何執行緒都會呼叫 ExitProcess 函式。 請注意,如果進程的主要執行緒傳回,C 執行時間程式庫的某些實作 (CRT) 呼叫 ExitProcess
  • 進程的最後一個執行緒會終止。
  • 任何執行緒都會使用進程的控制碼呼叫 TerminateProcess 函式。
  • 針對主控台進程,當主控台收到 CTRL+C 或 CTRL+BREAK 訊號時,預設 主控台控制項處理常式 會呼叫 ExitProcess
  • 使用者關閉系統或登出。

除非執行緒處於已知狀態,否則請勿終止進程。 如果執行緒正在等候核心物件,在等候完成之前將不會終止。 這可能會導致應用程式停止回應。

主要執行緒可以避免終止其他執行緒,方法是指示它們呼叫 ExitThread ,再造成進程終止 (以取得詳細資訊,請參閱 終止執行緒) 。 主要執行緒之後仍然可以呼叫 ExitProcess ,以確保所有線程都已終止。

進程的結束代碼是呼叫 ExitProcessTerminateProcess中指定的值,或是進程之 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 來終止其執行。

ExitProcessExitThreadCreateThread、CreateRemoteThreadCreateProcess函式的執行會在位址空間內序列化。 適用以下限制:

  • 在進程啟動和 DLL 初始化常式期間,可以建立新的執行緒,但除非進程完成 DLL 初始化,否則不會開始執行。
  • 一次只能有一個執行緒位於 DLL 初始化或卸離常式中。
  • 在 DLL 初始化或卸離常式中沒有線程之前, ExitProcess 函式不會傳回。