Поделиться через


Завершение процесса

Завершение процесса имеет следующие результаты:

  • Все остальные потоки в процессе помечены для завершения.
  • Все ресурсы, которые были выделены процессом, освобождаются.
  • Все объекты ядра закрыты.
  • Код процесса удаляется из памяти.
  • Код выхода процесса задается.
  • Объект процесса сигнализирует.

Хотя открытые дескрипторы для объектов ядра закрываются автоматически при завершении процесса, сами объекты существуют до тех пор, пока все открытые дескрипторы к ним не будут закрыты. Поэтому объект останется действительным после завершения процесса, который его использует, если другой процесс имеет к нему открытый дескриптор.

Функция GetExitCodeProcess возвращает состояние завершения процесса. Пока процесс выполняется, его статус завершения — по-прежнему АКТИВЕН. После завершения процесса состояние завершения процесса изменяется с STILL_ACTIVE на код выхода процесса.

После завершения процесса состояние объекта процесса становится сигналом, освобождая все потоки, ожидающие завершения процесса. Дополнительные сведения о синхронизации см. в разделе Синхронизация выполнения нескольких потоков.

При завершении процесса система не завершает дочерние процессы, созданные процессом. Завершение процесса не создает уведомления для процедур перехватчика WH_CBT.

Используйте функцию SetProcessShutdownParameters, чтобы указать определенные аспекты завершения процесса при завершении работы системы, например, когда процесс должен завершиться относительно других процессов в системе.

Как завершаются процессы

Процесс выполняется до тех пор, пока не произойдет одно из следующих событий:

  • Любой поток процесса вызывает функцию ExitProcess. Обратите внимание, что некоторые реализации библиотеки времени выполнения C (CRT) вызывают ExitProcess, если основной поток процесса возвращается.
  • Последний поток процесса завершается.
  • Любой поток вызывает функцию TerminateProcess с дескриптором процесса.
  • Для консольных процессов обработчик управления консоли по умолчанию вызывает вызовы ExitProcess, когда консоль получает сигнал CTRL+C или CTRL+BREAK.
  • Пользователь завершает работу системы или выключает его.

Не завершайте процесс, если его потоки не находятся в известных состояниях. Если поток ожидает объекта ядра, он не будет завершен до завершения ожидания. Это может привести к тому, что приложение перестанет отвечать.

Основной поток может избежать завершения других потоков, направляя их на вызов ExitThread до того как привести к завершению процесса (дополнительные сведения см. в разделе Прекращение потока). Основной поток по-прежнему может вызвать ExitProcess, чтобы гарантировать завершение всех потоков.

Код выхода для процесса — это значение, указанное в вызове ExitProcess или TerminateProcess, или значение, возвращаемое основным или функцией WinMain процесса. Если процесс завершается из-за неустранимого исключения, код выхода является значением исключения, вызвавшего завершение. Кроме того, это значение используется в качестве кода выхода для всех потоков, выполняемых при возникновении исключения.

Если процесс завершается ExitProcess, система вызывает функцию точки входа каждой подключенной DLL с параметром, показывающим, что процесс отключается от DLL. Библиотеки DLL не уведомляются при завершении процесса командой TerminateProcess. Дополнительные сведения о библиотеках DLL см. в Dynamic-Link библиотеках.

Если процесс завершается 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.
  • Функция ExitProcess не завершает выполнение, пока в потоках выполняются процедуры инициализации или отсоединения библиотек DLL.