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

Выполнение клонированного потомка начинается с функции childFunc(), которая получает файловый дескриптор (посредством аргумента arg), открытый главной программой (на шаге ). Потомок закрывает этот дескриптор и завершается, выполняя операцию return .


Листинг 28.3. Использование clone() для создания дочерних процессов

procexec/t_clone.c

#define _GNU_SOURCE

#include

#include

#include

#include

#include "tlpi_hdr.h"


#ifndef CHILD_SIG

#define CHILD_SIG SIGUSR1 /* При завершении клонированного потомка

будет сгенерирован сигнал */

#endif


static int /* Начальная функция для клонированного потомка */

childFunc(void *arg)

{

if (close(*((int *) arg)) == –1)

errExit("close");

return 0; /* Здесь потомок завершается */

}


int

main(int argc, char *argv[])

{

const int STACK_SIZE = 65536; /* Размер стека для клонированного потомка */

char *stack; /* Начало буфера стека */

char *stackTop; /* Конец буфера стека */

int s, fd, flags;


fd = open("/dev/null", O_RDWR); /* Потомок закроет дескриптор fd */

if (fd == –1)

errExit("open");


/* Если argc > 1, потомок будет разделять таблицу файловых дескрипторов с родителем */


flags = (argc > 1)? CLONE_FILES: 0;


/* Выделяем стек для потомка */


stack = malloc(STACK_SIZE);

if (stack == NULL)

errExit("malloc");

stackTop = stack + STACK_SIZE; /* Предполагается, что стек растет сверху вниз */


/* Игнорируем CHILD_SIG, если это сигнал, который по умолчанию завершает процесс;

при этом не игнорируем SIGCHLD (который игнорируется по умолчанию), иначе это

могло бы помешать созданию процесса-"зомби". */


if (CHILD_SIG!= 0 && CHILD_SIG!= SIGCHLD)

if (signal(CHILD_SIG, SIG_IGN) == SIG_ERR)

errExit("signal");


/* Создаем потомка; потомок начинает выполнение с функции childFunc() */

if (clone(childFunc, stackTop, flags | CHILD_SIG, (void *) &fd) == –1)

errExit("clone");

/* Родитель переходит сюда и ждет потомка; потомку, который применяет

для уведомления любой сигнал, кроме SIGCHLD, нужно значение _WCLONE. */


if (waitpid(–1, NULL, (CHILD_SIG!= SIGCHLD)? __WCLONE: 0) == –1)

errExit("waitpid");

printf("child has terminated\n");


/* Повлияло ли на родителя закрытие дескриптора в потомке? */


s = write(fd, "x", 1);

if (s == –1 && errno == EBADF)

printf("file descriptor %d has been closed\n", fd);

else if (s == –1)

printf("write() on file descriptor %d failed "

"unexpectedly (%s)\n", fd, strerror(errno));

else

printf("write() on file descriptor %d succeeded\n", fd);


exit(EXIT_SUCCESS);

}

procexec/t_clone.c

Запустив программу из листинга 28.3 без аргумента командной строки, мы получим следующий результат:

$ ./t_clone Не использует CLONE_FILES

child has terminated

write() on file descriptor 3 succeeded Вызов close() в потомке не влияет на родителя

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

$ ./t_clone x Использует CLONE_FILES

child has terminated

file descriptor 3 has been closed Вызов close() в потомке затрагивает родителя

Более сложный пример использования вызова clone() представлен в файле procexec/demo_clone.c, входящем в архив с исходным кодом для этой книги.


28.2.1. Аргумент flags вызова clone()

Аргумент flags вызова clone() представляет собой сочетание (побитовое ИЛИ) значений битовой маски, описанных на следующих страницах. Мы рассмотрим их в порядке, который облегчает объяснение; начнем с тех флагов, что применяются в реализации потоков выполнения POSIX. С этой точки зрения термин «процесс», многократно упоминающийся ниже, часто можно заменить словом «поток».

На данном этапе стоит отметить, что наши попытки провести грань между терминами «процесс» и «поток» в некоторой степени являются жонглированием словами. Это немного помогает при знакомстве с понятием единицы планирования ядра (Kernel Scheduling Entity, KSE); с его помощью в технической литературе иногда описывают объекты, с которыми работает планировщик ядра. На самом деле потоки и процессы являются всего лишь экземплярами KSE, поддерживающими разную степень совместного использования атрибутов (виртуальной памяти, дескрипторов открытых файлов, действий сигналов, идентификатора процесса и т. д.). Спецификация POSIX-потоков описывает лишь один из множества возможных способов разделения атрибутов между потоками.

По мере описания далее мы иногда будем упоминать две главные реализации POSIX-потоков, доступные в Linux: LinuxThreads (старую) и NTPL (более современную). Детальную информацию о них можно найти в разделе 33.5.

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

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

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

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

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