Окт 16

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

Процесс можно завершить четырьмя способами:
Входная функция первичного потока, например WinMain, возвращает управление (предпочтительный способ).
Один из потоков процесса вызывает функцию ExitProcess.
Поток другого процесса вызывает функцию TerminateProcess (нежелательный способ).
Все потоки процесса завершаются по своей воле. Но это случается очень редко.
Рекомендуется проектировать приложение так, чтобы его процесс завершался только после возврата управления функцией первичного потока. Это единственный способ, который гарантирует корректную очистку всех ресурсов, принадлежащих первичному потоку. При таком завершении любые объекты C++, созданные данным потоком, уничтожаются соответствующими деструкторами. Система освобождает память, которую занимал стек потока, и устанавливает код завершения процесса, который и возвращает входная функция.
Вы можете также завершить процесс, вызвав функцию ExitProcess. В справочных материалах MSDN этот способ указан как рекомендуемый. В то же время Дж. Рихтер указывает [5], что возможны ситуации, когда при данном способе завершения процесса не для всех объектов C++ будут вызваны деструкторы. Конечно, операционная система и в этом случае корректно очистит все ресурсы, выделенные процессу. Но при этом весьма вероятна утечка памяти или других ресурсов.
Вызов функции TerminateProcess тоже завершает процесс. Главное отличие этой функции от ExitProcess заключается в том, что ее может вызвать любой поток и завершить при этом любой процесс. Пользуйтесь функцией TerminateProcess лишь в крайнем случае, когда иным способом завершить процесс не удается. Процесс не получает абсолютно никаких уведомлений, что он завершается, и приложение не может выполнить очистку ресурсов или предотвратить свое неожиданное завершение. При этом теряются все данные, которые программа не успела переписать из памяти на диск. Но операционная система и в этом случае освобождает все принадлежавшие процессу ресурсы.
Четвертая ситуация может возникнуть, если все потоки вызвали ExitThread или они были закрыты другими потоками, вызвавшими функцию TerminateThread. Обнаружив, что в процессе нет исполняющихся потоков, операционная система немедленно завершает его. Код завершения процесса приравнивается к коду завершения последнего потока.
В случае завершения процесса системой выполняются следующие действия.
Выполнение всех потоков в процессе прекращается.
Все User- и GDI-объекты, созданные процессом, уничтожаются, а объекты ядра закрываются, если их не использует другой процесс.
Объект ядра «процесс» переходит в свободное, или незанятое (signaled), состояние.
Счетчик пользователей объекта ядра «процесс» уменьшается на единицу.