Читаем Linux API. Исчерпывающее руководство полностью

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


Дополнительная информация

Подробности реализации вызовов fork(), execve(), wait() и exit() в системах UNIX можно найти в книгах [Bach, 1986] и [Goodheart & Cox, 1994]. В книгах [Bovet & Cesati, 2005] и [Love, 2010] описаны особенности создания и завершения процессов в системе Linux.


24.7. Упражнения


24.1. Сколько новых процессов появится в результате выполнения программой следующей последовательности вызовов fork() (учитывая, что все они выполнятся успешно)?

fork();

fork();

fork();

24.2. Напишите программу, которая наглядно показывает, что после вызова vfork() дочерний процесс может закрыть файловый дескриптор (например, дескриптор под номером 0), без влияния на соответствующий дескриптор родителя.

24.3. Каким образом можно получить дамп памяти процесса в заданном месте программы, позволив исходному процессу продолжать выполнение (предполагается, что исходный код программы можно изменять)?

24.4. Поэкспериментируйте с программой из листинга 24.5 (fork_whos_on_first.c) на других реализациях UNIX, чтобы определить, как в них планируется выполнение родительского и дочернего процессов после вызова fork().

24.5. Представьте, что дочерний процесс в программе из листинга 24.6 тоже должен ждать, пока родитель не завершит какие-то действия. Какие изменения нужно будет внести в программу, чтобы этого добиться?

25. Завершение работы процесса

В этой главе рассматривается процедура завершения процесса. Мы начнем с описания вызовов exit() и _exit(), специально для этого предназначенных. Затем обсудим использование обработчиков выхода для автоматического освобождения ресурсов при вызове exit(). В заключение будут продемонстрированы некоторые способы взаимодействия между буферами stdio (стандартного ввода/вывода) и вызовами fork() и exit().


25.1. Завершение процесса: вызовы _exit() и exit()


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

#include


void _exit(int status);

Аргумент status, передаваемый вызову _exit(), определяет код завершения процесса, который доступен его родителю посредством вызова wait(). Этот аргумент имеет тип int, однако родительскому процессу доступны только последние 8 бит. Код 0 принято считать признаком успешного завершения, а любые другие значения сигнализируют о том, что процесс окончил работу с проблемами. Четких правил по интерпретации ненулевых значений не существует; разные приложения следуют своим собственным соглашениям, которые должны быть описаны в их документации. Стандарт SUSv3 определяет две константы, EXIT_SUCCESS (0) и EXIT_FAILURE (1), которые используются в большинстве примеров из этой книги.

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

Через аргумент status вызова _exit() родителю можно передать любое значение от 0 до 255, однако номера больше 128 могут вызвать неправильную работу скриптов командной строки. Дело в том, что при завершении программы с помощью сигнала командная оболочка сигнализирует об этом, присваивая переменной $? значение 128 плюс номер самого сигнала; это значение невозможно отличить от аналогичного, переданного в результате вызова _exit().

Программы обычно не вызывают _exit() напрямую, используя вместо этого библиотечную функцию exit(), которая выполняет различные предварительные действия.

#include


void exit(int status);

Функция exit() выполняет следующие приготовления перед вызовом _exit().

• Вызываются обработчики выхода (функции, зарегистрированные с помощью вызовов atexit() и on_exit()); в порядке, обратном их регистрации (см. раздел 25.3).

• Сбрасываются буферы потоков stdio.

• Выполняется системный вызов _exit() со значением, переданным в аргументе status.

В отличие от вызова _exit(), характерного для UNIX-систем, функция exit() является частью стандартной библиотеки С; это означает, что она доступна в любой реализации данного языка.

Другим способом завершения работы процесса является возвращение из функции main(), явное или неявное (когда достигается конец функции). Явный возврат значения (return n) обычно является эквивалентом вызова exit(n), поскольку среда выполнения, которая вызывает функцию main(), использует возвращаемое из нее значение для вызова exit().

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

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

Герберт Шилдт

Программирование, программы, базы данных