Прекращение процесса

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

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

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

Функция GetExitCodeProcess возвращает состояние завершения процесса. Во время выполнения процесса состояние его завершения — STILL_ACTIVE. Когда процесс завершается, его состояние завершения меняется с STILL_ACTIVE на код завершения процесса.

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

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

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

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

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

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

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

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

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

Если процесс завершается ExitProcess, система вызывает функцию точки входа каждой присоединенной библиотеки DLL со значением, указывающим, что процесс отсоединяется от библиотеки DLL. Библиотеки DLL не получают уведомления о завершении процесса с помощью TerminateProcess. Дополнительные сведения о библиотеках 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 может находиться только один поток за раз.
  • Функция ExitProcess не возвращается до тех пор, пока в их процедурах инициализации dll или отсоединения нет потоков.