Определение статуса завершения процесса — КиберПедия 

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...

Определение статуса завершения процесса

2021-01-29 70
Определение статуса завершения процесса 0.00 из 5.00 0 оценок
Заказать работу

 

Статус завершения (exit status) (известный также под другими именами значения завершения (exit value), кода возврата (return code) и возвращаемого значения (return value)) представляет собой 8‑битовое значение, которое родитель может использовать при завершении порожденного процесса (на языке Unix, «когда порожденный кончается (dies)»). По соглашению статус завершения 0 означает, что программа отработала без проблем. Любое ненулевое значение указывает на какую‑нибудь разновидность ошибки; программа определяет используемые числа и их значения, если они есть. (Например, использует 0 для указания, что образец был встречен по крайней мере один раз, 1 означает, что образец вообще не встретился, а 2 означает, что возникла ошибка.) Этот статус завершения доступен на уровне оболочки (для оболочек в стиле оболочки Борна) через специальную переменную.

Стандарт С определяет две константы, которые следует использовать для полной переносимости на не‑POSIX системы:

 

Программа завершилась без проблем. Для обозначения успеха может также использоваться ноль.

_FAILURE

В программе была какая‑нибудь проблема.

На практике использование лишь этих значений довольно ограничивает. Вместо этого следует выбрать небольшой набор кодов возврата, документировать их значения и использовать. (Например, 1 для ошибок опций командной строки и аргументов, 2 для ошибок ввода/вывода, 3 для ошибок данных и т.д.) Для удобочитаемости стоит использовать константы или значения. Слишком большой список ошибок делает их использование обременительным; в большинстве случаев вызывающая программа (или пользователь) интересуется лишь нулевым или ненулевым значением.

Когда достаточно двоичного разделения успех/неудача, педантичный программист использует и. Наш собственный стиль более естественный, используя с и явные константы 0 или 1. Это настолько обычно, что рано заучивается и быстро становится второй натурой. Однако для своих проектов вы сами должны принять решение.

 

ЗАМЕЧАНИЕ. Для родительского процесса доступны лишь восемь наименее значимых битов значения. Поэтому следует использовать значения в диапазоне 0–255. Как мы вскоре увидим, у чисел 126 и 127 есть традиционные значения (помимо простого «неуспешно»), которых ваши программы должны придерживаться.

Поскольку имеют значение лишь восемь наименее значимых битов, вы никогда не должны использовать отрицательные статусы завершения. Когда из небольших отрицательных чисел выделяются восемь последних битов, они превращаются в большие положительные значения! (Например. ‑1 становится 255, а ‑5 становится 251.) Мы видели книги по программированию на С, в которых это понималось неправильно – не дайте сбить себя с толку

 

 

Возвращение из

 

Программа может естественно завершиться одним из двух способов: посредством использования одной из описанных далее функций или возвратившись из. (Третий, более радикальный способ описан далее в разделе 12.4 «Совершение самоубийства:».) В последнем случае следует использовать явное возвращаемое значение вместо выпадения в конце функции:

 

 

Стандарт С 1999 г. указывает, что при выпадении в конце, поведение функции должно быть таким, как если бы она возвращала 0. (Это верно также для С++; однако, стандарт С 1989 г. намеренно оставляет этот случай неопределенным.) Во всех случаях плохо полагаться на это поведение; однажды вы можете программировать для системы со скудной поддержкой С времени исполнения, или для внедренной системы, или где‑то еще, где это будет по‑другому. (В общем, выпадение в конце любой функции, не являющейся – плохая мысль, которая может вести лишь к ошибочному коду.)

Возвращенное из значение автоматически передается обратно системе, от которой родительский процесс может его впоследствии получить. Мы опишем, как это делается, в разделе 9.1.6.1 «Использование функций POSIX: и».

 

ЗАМЕЧАНИЕ. На системах GNU/Linux управляемая компилятором команда c99 запускает компилятор с соответствующими опциями, так что возвращаемое значение при выпадении из конца функции равно 0. Простой gcc этого не делает.

 

 

Функции завершения

 

Другим способом естественного завершения программы является вызов функций завершения. Стандарт С определяет следующие функции:

 

Эти функции работают следующим образом:

 

Эта функция завершает программу, передается системе для использования родителем. Перед завершением программы вызывает все функции, зарегистрированные с помощью, сбрасывает на диск и закрывает все открытые потоки <* и удаляет все временные файлы, созданные (см. раздел 12.3.2 «Создание и открытие временных файлов»). Когда процесс завершается, ядро закрывает любые оставшиеся открытыми файлы (которые были открыты посредством, или через наследование дескрипторов), освобождает его адресное пространство и освобождает любые другие ресурсы, которые он мог использовать. никогда не возвращается.

 

Эта функция в сущности идентична функции POSIX; мы на короткое время отложим ее обсуждение,

 

 является указателем на функцию обратного вызова, которая должна вызываться при завершении программы, запускает функцию обратного вызова перед закрытием файлов и завершением. Идея в том, что приложение может предоставить одну или более функций очистки, которые должны быть запущены перед окончательным завершением работы. Предоставление функции называется ее регистрацией. (Функции обратного вызова для обсуждались в разделе 8.4.3.2 «Функция обратного вызова»; здесь та же идея, хотя вызывает каждую зарегистрированную функцию лишь однажды.)

 возвращает 0 при успехе или ‑1 при неудаче и соответствующим образом устанавливает.

Следующая программа не делает полезной работы, но демонстрирует, как работает:

 

Вот что происходит при запуске:

ch09‑atexit

 

 

Как показывает пример, функции, зарегистрированные с помощью, запускаются в порядке, обратном порядку их регистрации: последние первыми. (Это обозначается также LIFO – last‑in‑first‑out – вошедший последним выходит первым).

POSIX определяет функцию. В отличие от, которая вызывает функции обратного вызова и выполняет ‑очистку, является «сразу заканчивающейся» функцией:

 

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

На практике функция ISO С идентична. Стандарт С говорит, что от реализации функции зависит, вызывает ли зарегистрированные функции и закрывает ли открытые файлы. Для систем GLIBC это не так, и функция ведет себя подобно.

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

Например, предположим, что вы хотите запустить команду оболочки и хотите сами выполнить и. Такой код выглядел бы следующим образом:

 

Проверка значения и завершающего значения следуют соглашениям, используемым оболочкой POSIX. Если запрошенная программа не существует (– нет для неё элемента в каталоге), завершающее значение равно 127. В противном случае, файл существует, но не могла быть выполнена по какой‑то другой причине, поэтому статус завершения равен 126. Хорошая мысль следовать этим соглашениям также и в ваших программах. Вкратце, чтобы хорошо использовать и, следует делать следующее:

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

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

• Использовать для выхода из программы во всех местах, когда что‑то идет не так и когда выход является правильным действием. Используйте коды ошибок, которые определили.

• Исключением является, для которой можно использовать при желании. Наш собственный стиль заключается обычно в использовании при наличии проблем и '' в конце, если все прошло хорошо.

• Использовать или в порожденном процессе, если exec() завершается неудачей.

 

 


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

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...

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

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.013 с.