Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа по процессам full.doc
Скачиваний:
7
Добавлен:
19.12.2018
Размер:
375.3 Кб
Скачать

10.3. Функция TerminateProcess

Вызов функции TerminateProcess тоже завершает процесс:

BOOL TerminateProcess( HANDLE hProcess, UINT fuExitCode);

Главное отличие этой функции от ExitProcess в том, что ее может вызвать любой поток и завершить любой процесс. Параметр hProcess идентифицирует описатель завершаемого процесса, а в параметре fuExitCode возвращается код завершения процесса.

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

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

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

Замечание: TerminateProcess — функция асинхронная, т. e. она сообщает системе, что необходимо завершить процесс, но к тому времени, когда она вернет управление, процесс может быть еще не уничтожен. Так что, если необходимо точно знать момент завершения процесса, используйте WaitForSingleObject или аналогичную функцию, передав ей описатель этого процесса.

10.4.Завершение всех процессов потока

В такой ситуации (она может возникнуть, если все потоки вызвали ExitThread или их закрыли вызовом TerminateThread) операционная система больше не считает нужным «содержать» адресное пространство данного процесса. Обнаружив, что в процессе не исполняется ни один поток, она немедленно завершает его. При этом код завершения процесса приравнивается коду завершения последнего потока.

11. Порядок завершения процесса

При завершении процесс происходит следующее:

  1. Выполнение всех потоков в процессе прекращается

  2. Все User- и GDI-объекты, созданные процессом, уничтожаются, а объекты ядра закрываются (если их не использует другой процесс).

  3. Код завершения процесса меняется со значения STILL_ACTIVE на код, переданный в ExitProcess или TerminateProcess.

  4. Объект ядра «процесс» переходит в свободное, или незанятое (signaled), состояние Прочие потоки в системе могут при остановить свое выполнение вплоть до завершения данного процесса.

  5. Счетчик объекта ядра «процесс» уменьшается на единицу.

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

По завершении процесса его код и выделенные ему ресурсы удаляются из памяти. Однако область памяти, выделенная системой для объекта ядра «процесс», не освобождается, пока счетчик числа его пользователей не достигнет нуля. А это произойдет, когда все прочие процессы, создавшие или открывшие описатели для ныне покойного процесса, уведомят систему (вызовом CloseHandle) о том, что ссылки па этот процесс им больше не нужны.

Описатели завершенного процессса уже мало на что пригодны. Разве что родительский процесс, вызвав функцию GetExitCodeProcess, может проверигь, завершен ли процесс, идентифицируемый параметром hProcess, и, если да, определить код завершения:

BOOL GetExitCodeProcess( HANDLE hProcess, PDWORD pdwExitCode);

Код завершения возвращается как значение типа DWORD, на которое указывает pdwExitCode. Если на момент вызова GetExitCodeProcess процесс еще не завершился, в DWORD заносится идентификатор STILL_ACTIVE (определенный как 0x103) А если он уничтожен, функция возвращает реальный код его завершения.

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