Читаем Linux программирование в примерах полностью

На языке Unix, помимо названия системного вызова, слово «fork» является и глаголом, и существительным[88]. Мы можем сказать, что «один процесс ответвляет другой», и что «после разветвления работают два процесса». (Думайте «развилка (fork) на дороге», а не «вилка (fork), нож и ложка».)

<p>9.1.1.1. После <code>fork()</code>: общие и различные атрибуты</p>

Порожденный процесс «наследует» идентичные копии большого числа атрибутов от родителя. Многие из этих атрибутов специализированы и здесь неуместны. Поэтому следующий список намеренно неполон. Существенны следующие:

• Окружение, см. раздел 2.4 «Окружение».

• Все открытые файлы и открытые каталоги; см. раздел 4.4.1 «Понятие о дескрипторах файлов» и раздел 5.3.1 «Базовое чтение каталогов».

• Установки umask; см. раздел 4.6 «Создание файлов».

• Текущий рабочий каталог; см раздел 8.4.1 «Смена каталога: chdir() и fchdir().

• Корневой каталог; см. раздел 8.6 «Изменение корневого каталога: chroot()».

• Текущий приоритет (иначе называемый «значение nice»; вскоре мы это обсудим; см раздел 9.1.3 «Установка приоритета процесса: nice()»).

• Управляющие терминалы. Это устройство терминала (физическая консоль или окно эмулятора терминала), которому разрешено посылать процессу сигналы (такие, как CTRL-Z для прекращения выполняющихся работ). Это обсуждается далее в разделе 9.2.1 «Обзор управления работой».

• Маска сигналов процесса и расположение всех текущих сигналов (еще не обсуждалось; см. главу 10 «Сигналы»).

• Реальный, эффективный и сохраненный ID пользователя, группы и набора дополнительных групп (еще не обсуждалось; см. главу 11 «Права доступа и ID пользователя и группы»).

Помимо возвращаемого значения fork() два процесса различаются следующим образом:

• У каждого есть уникальный ID процесса и ID родительского процесса (PID и PPID) Они описаны в разделе 9.1.2 «Идентификация процесса: getpid() и getppid()».

• PID порожденного процесса не будет равняться ID любой существующей группы процессов (см. раздел 9.2 «Группы процессов»).

• Аккумулированное время использования процессора для порожденного процесса и его будущих потомков инициализируется нулем. (Это имеет смысл; в конце концов, это совершенно новый процесс.)

• Любые сигналы, которые были ожидающими в родительском процессе, в порожденном сбрасываются, также как ожидающие аварийные сигналы и таймеры. (Мы еще не рассматривали эти темы; см. главу 10 «Сигналы» и раздел 14.3.3 «Интервальные таймеры: setitimer() и getitimer()».)

• Блокировки файлов в родительском процессе не дублируются в порожденном (также еще не обсуждалось; см. раздел 14.2 «Блокировка файлов»).

<p>9.1.1.2. Разделение дескрипторов файлов</p>

Атрибуты, которые порожденный процесс наследует от родителя, устанавливаются в те же значения, которые были в родительском процессе в момент выполнения fork(). Однако, с этого момента два процесса продолжают идти собственными путями (большей частью) независимо один от другого. Например, если порожденный процесс изменяет каталог, каталог родительского процесса не затрагивается. Сходным образом, если порожденный изменяет среду, среда родителя не меняется.

Открытые файлы являются важным исключением из этого правила. Дескрипторы открытых файлов являются разделяемыми, и действия одного процесса с разделяемым дескриптором файла затрагивает состояние файла также и для другого процесса. Это лучше всего понять, изучив рис. 9.1.

Рис. 9.1. Разделение дескрипторов файлов

Рисунок отображает внутренние структуры данных ядра. Ключевой структурой данных является таблица файлов. Каждый элемент ссылается на открытый файл. Помимо других учетных данных, таблица файлов содержит текущее положение (смещение чтения/записи) в файле. Оно устанавливается либо автоматически каждый раз при чтении или записи файла, либо непосредственно через lseek() (см. раздел 4.5 «Произвольный доступ: перемещения внутри файла»).

Дескриптор файла, возвращенный функциями open() или creat(), действует как индекс имеющегося в каждом процессе массива указателей на таблицу файлов. Размер этого массива не превышает значение, возвращенное getdtablesize() (см. раздел 4.4.1 «Понятие о дескрипторах файлов»).

На рис. 9.1 показаны два процесса, разделяющие стандартный ввод и стандартный вывод; для каждого из процессов указаны одни и те же элементы в таблице файлов. Поэтому, когда процесс 45 (порожденный) осуществляет read(), общее смещение обновляется; следующий раз, когда процесс 42 (родитель) осуществляет read(), он начинает с позиции, в которой закончила чтение read() процесса 45.

Это легко можно видеть на уровне оболочки:

$ cat data /* Показать содержание демонстрационного файла */

line 1

line 2

line 3

line 4

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

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

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

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

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

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

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