Возврат управления входной функцией первичного потока



 

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

  • любые С++ - объекты, созданные данным потоком, уничтожаются соответствующими деструкторами;
  • система освобождает память, которую занимал стек потока;
  • система устанавливает код завершения процесса (поддерживаемый объектом ядра "процесс") — его и возвращает Ваша входная функция;
  • счетчик пользователей данного объекта ядра "процесс" уменьшается на 1.

 

Функция ExitProcess

 

Процесс завершается, когда один из его потоков вызывает ExitProcess :

 

     void ExitProcess(UINT fuExitCode);

Эта функция завершает процесс и заносит в параметр fuExitCode код завершения процесса. Возвращаемого значения у ExitProcess нет, так как результат ее действия — завершение процесса. Если за вызовом этой функции в программе присутствует какой-нибудь код, он никогда не исполняется.

Когда входная функция (WinMain или mai n ) в Вашей программе возвращает управление, оно передастся стартовому коду из библиотеки С/C++, и тот проводит очистку всех ресурсов, выделенных им процессу, а затем обращается к ExitProcess , передавая ей значение, возвращенное входной функцией. Вот почему возврат управления входной функцией первичного потока приводит к завершению всего процесса. Обратите внимание, что при завершении процесса прекращается выполнение и всех других его потоков.

 

Функция TerminateProcess

 

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

 

bool TerminateProcess( HANDLE hProcess, UINT fuExitCode);

 

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

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

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

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

 

    Завершенный процесс не оставляет за собой никаких следов.

 

Когда все потоки процесса завершаются

 

В такой ситуации (а она может возникнуть, если все потоки вызвали ExitT h read или их закрыли вызовом Termi nateT h read)операционная система больше не считает нужным "содержать" адресное пространство данного процесса. Обнаружив, что в процессе не исполняется ни один поток, она немедленно завершает его. При этом код завершения процесса приравнивается коду завершения последнего потока.

 

Что происходит при завершении процесса

 

  1. Выполнение всех потоков в процессе прекращается.
  2. Все User- и GDI-объекты, созданные процессом, уничтожаются, а объекты ядра закрываются (если их не использует другой процесс).
  3. Код завершения процесса меняется со значения STILL_ACTIVE на код, переданный в ExitProcess или TerminateProcess .
  4. Объект ядра "процесс" переходит в свободное, или незанятое (signaled), состояние. Прочие потоки в системе могут приостановить свое выполнение вплоть до завершения данного процесса.
  5. Счетчик объекта ядра "процесс" уменьшается на 1.

 

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

 

Закрытие процесса не приводит к автоматическому завершению

порожденных им процессов.

 

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

 


Дата добавления: 2019-07-15; просмотров: 253; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!