Linux программирование в примерах
Шрифт:
В данной главе картина начинает усложняться. В частности, для полноты мы должны упомянуть о вещах, которые не будут рассматриваться до конца главы или до конца книги В таких случаях мы предусмотрели ссылки вперед, но вы должны быть способны без подготовки уловить суть каждого раздела.
9.1. Создание и управление процессами
В отличие от многих предшествующих и последующих операционных систем, создание процессов в Unix задумывалось (и было сделано) дешевым. Более того, Unix разделяет идеи «создания нового процесса» и «запуска данной программы в процессе». Это было элегантное проектное решение,
9.1.1. Создание процесса:
Первым шагом в запуске новой программы является вызов
Использование
Вот ключ: оба процесса выполняют одну и ту же программу. Два процесса могут различить себя, основываясь на возвращённом
Отрицательное
Если была ошибка,
Нулевое
В порожденном процессе
Положительное
В родительском процессе
Код шаблона для создания порожденного процесса выглядит следующим образом:
На языке Unix, помимо названия системного вызова, слово «fork» является и глаголом, и существительным [88] . Мы можем сказать, что «один процесс ответвляет другой», и что «после разветвления работают два процесса». (Думайте «развилка (fork) на дороге», а не «вилка (fork), нож и ложка».)
9.1.1.1. После
Порожденный процесс «наследует» идентичные копии большого числа атрибутов от родителя. Многие из этих атрибутов специализированы и здесь неуместны. Поэтому следующий список намеренно неполон. Существенны следующие:
88
Fork (англ.) —
• Окружение, см. раздел 2.4 «Окружение».
• Все открытые файлы и открытые каталоги; см. раздел 4.4.1 «Понятие о дескрипторах файлов» и раздел 5.3.1 «Базовое чтение каталогов».
• Установки umask; см. раздел 4.6 «Создание файлов».
• Текущий рабочий каталог; см раздел 8.4.1 «Смена каталога:
• Корневой каталог; см. раздел 8.6 «Изменение корневого каталога:
• Текущий приоритет (иначе называемый «значение nice»; вскоре мы это обсудим; см раздел 9.1.3 «Установка приоритета процесса:
• Управляющие терминалы. Это устройство терминала (физическая консоль или окно эмулятора терминала), которому разрешено посылать процессу сигналы (такие, как CTRL-Z для прекращения выполняющихся работ). Это обсуждается далее в разделе 9.2.1 «Обзор управления работой».
• Маска сигналов процесса и расположение всех текущих сигналов (еще не обсуждалось; см. главу 10 «Сигналы»).
• Реальный, эффективный и сохраненный ID пользователя, группы и набора дополнительных групп (еще не обсуждалось; см. главу 11 «Права доступа и ID пользователя и группы»).
Помимо возвращаемого значения
• У каждого есть уникальный ID процесса и ID родительского процесса (PID и PPID) Они описаны в разделе 9.1.2 «Идентификация процесса:
• PID порожденного процесса не будет равняться ID любой существующей группы процессов (см. раздел 9.2 «Группы процессов»).
• Аккумулированное время использования процессора для порожденного процесса и его будущих потомков инициализируется нулем. (Это имеет смысл; в конце концов, это совершенно новый процесс.)
• Любые сигналы, которые были ожидающими в родительском процессе, в порожденном сбрасываются, также как ожидающие аварийные сигналы и таймеры. (Мы еще не рассматривали эти темы; см. главу 10 «Сигналы» и раздел 14.3.3 «Интервальные таймеры:
• Блокировки файлов в родительском процессе не дублируются в порожденном (также еще не обсуждалось; см. раздел 14.2 «Блокировка файлов»).
9.1.1.2. Разделение дескрипторов файлов
Атрибуты, которые порожденный процесс наследует от родителя, устанавливаются в те же значения, которые были в родительском процессе в момент выполнения
Открытые файлы являются важным исключением из этого правила. Дескрипторы открытых файлов являются разделяемыми, и действия одного процесса с разделяемым дескриптором файла затрагивает состояние файла также и для другого процесса. Это лучше всего понять, изучив рис. 9.1.