Статьи по Assembler


Старт и завершение приложений - часть 3


 

В ОС Windows существует множество способов закончить работу приложения. В MSDN сказано, что это произойдет, если:

  • любой из потоков приложения вызовет функцию ExitProcess
  • первичный поток приложения завершится командой ret Завершение первичного потока вызовом функции ExitThread в случае наличия других потоков не приведет к завершению приложения.
  • завершится (любым способом) последний из потоков приложения
  • любой из потоков приложения вызовет функцию TerminateProcess
  • консольное приложение получит от пользователя сигнал CTRL+C (CTRI+BREAK)
  • завершится работа системы (shut down) или работа пользователя в системе (log off).

Надо сказать, что этот список не окончателен. Николай Критский (nkritsky@mail.ru) подсказал еще и такой экзотический, но вполне работоспособный вариант: функцией SetErrorMode отключить выдачу системных сообщений об ошибках, а затем искусственно создать такую ошибку (например, выполнив деление на 0). Возникшая при этом исключительная ситуация приведет к завершению работы приложения.

На самом деле перечисленное разнообразие - только кажущееся, так как некоторые из указанных вариантов - это всего лишь скрытый вызов все той же функции ExitProcess. Это касается и ret в первичном потоке, и CTRL+C для консольного приложения, и даже варианта Николая Критского. Фактически в этих вариантах управление передается в существующие по умолчанию runtime-модуль, процедуру поддержки консоли или обработчик исключительной ситуации, которые и вызовут функцию ExitProcess.

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

  1. Все занятые приложением dll-библиотеки будут освобождены, то есть для каждой из них будет вызвана входная функция со параметрами отключения. При этом внутренние счетчики занятости библиотек будут декрементированы, и те библиотеки, счетчики которых достигнут 0, будут выгружены из системы.
  2. Будут закрыты все дескрипторы объектов, существовавшие в приложении
  3. Будет завершена работа всех потоков приложения
  4. Объект приложения перейдет в состояние "установлен", так что если кто-то в системе ждал завершения работы нашего приложения, сразу узнает об этом
  5. Все объекты потоков приложения также перейдут в состояние "установлен"
  6. Статус завершения процесса изменится со значения STILL_ACTIVE на значение, переданное функции ExitProcess

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

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

 

См. также статьи минимальное приложение и параметры функции WinMain.






- Начало -  - Назад -  - Вперед -



Книжный магазин