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

Основными элементами этой и нескольких следующих глав являются системные вызовы fork(), exit(), wait() и execve(). Каждый из них имеет свои вариации, которые мы тоже не обойдем стороной. Пока что ознакомимся с кратким описанием этих четырех вызовов и узнаем, как они обычно используются в связке друг с другом.

• Системный вызов fork() позволяет одному процессу, родителю, создавать новый, дочерний процесс. Оба этих процесса являются (почти) идентичными: потомок получает копии родительского стека, данных, кучи, копии родительских сегментов стека Х(см. раздел 6.3) и текста. Термин fork («вилка», «разветвление») стали применять потому, что родительский процесс как бы делится на две копии самого себя.

• Библиотечная функция exit(status) завершает процесс, делая все его ресурсы (память, дескрипторы открытых файлов и т. д.) доступными для последующего перераспределения ядром. Аргумент status — целое число, которое определяет код завершения процесса. Родительский процесс может извлечь этот код с помощью системного вызова wait().

Библиотечная функция exit() является оберткой вокруг системного вызова _exit(). В главе 25 вы узнаете разницу между этими двумя интерфейсами. А пока достаточно помнить о том, что обычно с помощью вызова exit() завершают работу только одного родителя или потомка, порожденного вызовом fork(); остальные процессы следует завершать с помощью вызова _exit().

• Системный вызов wait(&status) имеет два назначения. Во-первых, если работа потомка текущего процесса еще не была завершена путем вызова exit(), функция wait() приостанавливает выполнение родителя, пока не будет завершен один из его потомков. Во-вторых, код завершения потомка возвращается через аргумент функции wait().

• Системный вызов execve(pathname, argv, envp) загружает в память процесса новую программу (расположенную в pathname, с аргументами argv и списком переменных среды envp). Текст существующей программы сбрасывается, а для новой программы заново создаются сегменты со стеком, данными и кучей. Эту операцию часто называют выполнением новой программы. Позже вы познакомитесь с несколькими функциями, которые являются обертками вокруг execve(), каждая из которых предоставляет полезную разновидность этого программного интерфейса. В случаях, когда эти разновидности не имеют принципиального значения, мы будем ссылаться на них с помощью обобщенного названия exec(), но имейте в виду, что системных вызовов или библиотечных функций с таким именем не существует.

В некоторых других операционных системах возможности функций fork() и exec() объединены в одну операцию — порождение (spawn); она создает новый процесс, который выполняет заданную программу. Однако подход, используемый в системах UNIX, обычно является более простым и изящным. Разделение этих двух шагов упрощает программные интерфейсы (системный вызов fork() не принимает аргументы) и делает программу более гибкой, позволяя ей выполнять определенные действия между этими двумя этапами. Кроме того, вызов fork() часто имеет смысл делать без последующего вызова exec().

Стандарт SUSv3 предусматривает дополнительную функцию posix_spawn(), которая объединяет возможности fork() и exec(). В системе Linux она и еще несколько связанных программных интерфейсов, описанных в стандарте SUSv3, реализована в библиотеке glibc. Функция posix_spawn() позволяет создавать переносимые приложения с поддержкой аппаратных архитектур, которые не предоставляют механизм файла подкачки или блоки управления памятью (что характерно для многих встраиваемых систем). В рамках таких архитектур реализация традиционного вызова fork() является либо затруднительной, либо невозможной в принципе.

На рис. 24.1 показано, как вызовы fork(), exit(), wait() и execve() обычно используются вместе (эта диаграмма изображает пошаговые действия командной оболочки, выполняющей команду: создается непрерывный цикл, в котором оболочка считывает команду, обрабатывает ее различными способами, после чего создает дочерний процесс для ее выполнения).

Применение вызова execve(), показанное на этой диаграмме, не является обязательным. Иногда имеет смысл позволить потомку продолжить выполнение программы родителя. В любом случае выполнение дочернего процесса в конечном счете завершается вызовом exit() (или передачей сигнала) и возвращением кода завершения, доступным родителю через функцию wait(). Вызов wait() тоже необязателен. Родитель может просто игнорировать своего потомка и продолжать работу. Однако позже мы увидим, что использование функции wait() обычно является желательным и выполняется внутри обработчика сигнала SIGCHLD, который генерируется ядром для родителя, когда один из его дочерних процессов завершается (по умолчанию сигнал SIGCHLD игнорируется, поэтому в диаграмме сказано, что его доставка является опциональной).


24.2. Создание нового процесса: fork()


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

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

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#.Введите сюда краткую аннотацию

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

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