Завершение процесса
Завершение процесса имеет следующие результаты:
- Все остальные потоки в процессе помечены для завершения.
- Все ресурсы, которые были выделены процессом, освобождаются.
- Все объекты ядра закрыты.
- Код процесса удаляется из памяти.
- Код выхода процесса задается.
- Объект процесса сигнализирует.
Хотя открытые дескрипторы для объектов ядра закрываются автоматически при завершении процесса, сами объекты существуют до тех пор, пока все открытые дескрипторы к ним не будут закрыты. Поэтому объект останется действительным после завершения процесса, который его использует, если другой процесс имеет к нему открытый дескриптор.
Функция 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.