Четыре события, приводящие к завершению процесса:
− Плановое завершение (окончание выполнения)
− Плановый выход по известной ошибке (например, отсутствие файла)
− Выход по неисправимой ошибке (ошибка в программе)
− Уничтожение другим процессом
Процесс может быть завершен вызовом одной из двух функций –ExitProcess() или TerminateProcess().
Функция ExitProcess() завершает процесс и все его потоки и возвращает обычный код завершения. Это дает возможность четкой остановки процесса, включая и выполнение кода отсоединения процесса от всех связанных с ним библиотек DLL. Синтаксис функции следующий
VOID ExitProcess(UINT uExitCode)
Параметр:
uExitCode – код завершения процесса.
Завершение процесса начинается изнутри процесса. Причины:
1. Только поток процесса знает, когда он выполнил свою работу и когда ему необходимо завершиться.
2. Только процесс в тот момент, когда он узнает о необходимости завершения, может оповестить об этом все принадлежащие ему потоки и произвести нормальное завершение. Извне процесса эти действия произвести почти невозможно.
При завершении процесса производятся следующие действия:
- вызываются функции деинициализации всех подключенных библиотек динамической компоновки, т.е. происходит нормальное завершение всех подключенных DLL;
- закрываются и/или уничтожаются все объекты, открытые и/или созданные процессом;
- состояние процесса изменяется на "освобожденный" (signaled), что является сигналом для всех потоков, ожидающих завершения процесса;
- состояние всех потоков изменяется на "освобожденный" (signaled), что является сигналом для всех потоков других процессов, которые ожидают завершения потоков текущего процесса;
- код завершения меняется со STILL_ACTIVE на код, записываемый в uExitCode;
- счетчик числа пользователей процесса уменьшается на единицу (заметим, что данные процесса удаляются из памяти, но сам объект остается в памяти до того момента, пока счетчик пользователей не достигнет нулевого значения, или, другими словами, пока не будут закрыты все хэндлы процесса.
Определить, завершен ли процесс можно с помощью функции GetExitProcessCode(), которая в случае незавершенности процесса возвращает STILL_ACTIVE.
Необходимо отметить, что завершение процесса не приводит к завершению порожденных им процессов.
Функция TerminateProcess() является аварийным средством завершения процесса и её рекомендуется использовать только в крайнем случае. Функция используется только тогда, когда иными средствами завершить процесс не удается. С этой целью извне (!), а не изнутри процесса вызывается функция TertninateProcess(), которая и завершает процесс. Но в данном случае не освобождаются используемые процессом DLL, хотя все используемые объекты и память, занимаемая процессом, освобождаются. Число пользователей процесса также уменьшается. Синтаксис функции следующий.
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
Параметры:
hProcess – хэндл объекта завершаемого процесса.
uExitCode – код завершения процесса.
Возвращаемое значение: если выполнение завершения произошло удачно, то TRUE, иначе - FALSE.