Из Расширенного программирования в среде UNIX У. Ричарда Стивенса (стр. 188):
8,3
fork
функцияТолько путь новый процесс создается ядром Unix, когда существующий процесс вызывает
fork
функцию. (Это не относится к специальным процессам, которые мы упомянули в предыдущем разделе -init
swapper и pagedaemon. Эти процессы специально создаются ядром как часть начальной загрузки.)#include <sys/types.h> #include <unistd.h> pid_t fork(void); /* Returns: 0 in child, process ID of child in parent, -1 on error */
Новый созданный процесс
fork
называется дочерним процессом . Функция вызывается один раз, но возвращается дважды. Единственная разница в возвращаемых значениях заключается в том, что возвращаемое значение в дочернем элементе равно 0, а возвращаемое значение в родительском элементе является идентификатором процесса нового дочернего элемента. Причина, по которой идентификатор дочернего процесса возвращается родителю, состоит в том, что у процесса может быть более одного дочернего элемента, поэтому нет функции, которая позволяла бы процессу получать идентификаторы процессов своих дочерних элементов. Причинаfork
возвращает 0 дочернему элементу в том, что у процесса может быть только один родительский элемент, поэтому дочерний элемент всегда может вызыватьgetppid
для получения идентификатора процесса своего родительского элемента. (Идентификатор процесса 0 всегда используется подкачкой, поэтому 0 не может быть идентификатором процесса дочернего элемента.)И ребенок, и родитель продолжают выполнение с инструкцией, следующей за вызовом
fork
. Ребенок является копией родителя. Например, потомок получает копию пространства данных, кучи и стека родителя. Обратите внимание, что это копия для дочернего элемента - родитель и дочерний элемент не разделяют эти части памяти. Часто родитель и потомок разделяют текстовый сегмент (раздел 7.6), если он доступен только для чтения.
В Linux fork
оператор Perl вызывает систему fork
и возвращает undef
при ошибке, а не -1.
Стивенс приводит списки (стр. 192) наследуемых свойств и различий между родительскими процессами и их раздвоенными детьми:
Помимо открытых файлов, существует множество других свойств родителя, которые наследуются дочерним элементом:
- реальный идентификатор пользователя, реальный идентификатор группы, эффективный идентификатор пользователя, эффективный идентификатор группы
- идентификаторы дополнительных групп
- ID группы процессов
- идентификатор сессии
- управляющий терминал
- флаг set-user-ID и флаг set-group-ID
- текущий рабочий каталог
- корневая директория
- маска создания режима файла
- сигнальная маска и диспозиции
- флаг close-on-exec для любых открытых файловых дескрипторов
- среда
- прикрепленные сегменты общей памяти
- пределы ресурса
Различия между родителем и ребенком
- возвращаемое значение от
fork
- идентификаторы процессов разные
- два процесса имеют разные идентификаторы родительских процессов - родительский идентификатор родительского процесса; идентификатор родительского процесса не меняется
- ценности ребенка для
tms_utime
,tms_stime
,tms_cutime
иtms_ustime
устанавливаются в 0- блокировки файлов, установленные родителем, не наследуются дочерним
- ожидающие тревоги очищаются для ребенка
- набор ожидающих сигналов для ребенка устанавливается в пустой набор