[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Системный вызов fork(2)

Эта иллюстрация показывает родительский процесс до вызова fork(2) и
после того, как этот вызов возвратил управление. После fork(2)
исполняются два процесса с различными идентификаторами.  Сегменты
текста, данных и стека у родительского и порожденного процессов
идентичны. Для программы с разделяемым текстом (компилятор по
умолчанию создает именно такие программы) текст в действительности
будет одним и тем же физическим сегментом, после fork(2) только
увеличится счетчик ссылок на него. Оба процесса имеют почти одинаковые
пользовательские области. Так как пользовательская область содержит
таблицу дескрипторов файлов, все перенаправления ввода/вывода,
сделанные в родительском процессе, наследуются потомком. Захваты
файлов являются собственностью процесса, поэтому подпроцесс не
унаследует захватов файлов, сделанных родителем. Отображение файлов на
память при fork(2) сохраняется.
В этом примере fork(2) возвращает 12793 родительскому процессу 12791.
fork(2) возвращает 0 вновь порожденному процессу 12793.

                   Системный вызов fork(2) - Пример

Этот пример иллюстрирует создание подпроцесса. После fork(2) два
процесса будут исполнять одну и ту же программу. Они оба распечатают
свой идентификатор процесса и идентификатор родителя.
Эта программа работает следующим образом:
   8-9    Процесс  распечатывает  идентификатор  своего  родительского
          процесса - обычно идентификатор процесса входного shell'а.

   11     Создается  новый   процесс.  Новый   (порожденный)   процесс
          является точной копией вызывающего процесса (родителя).

   13-14  Оба процесса исполняют этот оператор.

Файл: fork0.c
Замечание: Вызов getppid(2), исполняемый вновь порожденным процессом,
может возвратить идентификатор процесса 1, то есть процесса init.
После fork(2) родительский и порожденный процесс исполняются
независимо. Родитель может завершиться раньше, чем порожденный,
особенно если он выполняет меньше действий. Если родительский процесс
завершается раньше порожденного, то последний "усыновляется" процессом
init. В этом случае система устанавливает процесс с идентификатором 1
в качестве родителя подпроцесса.
                   СИСТЕМНЫЙ ВЫЗОВ fork(2) - ПРИМЕР

 1 #include <sys/types.h>
 2 #include <unistd.h>
 3 #include <stdio.h>
 4
 5 main()
 6 {
 7
 8         printf("[%ld] parent process id: %ld\n",
 9         getpid(), getppid());
10
11         fork();
12
13         printf("\n\t[%ld] parent process id: %ld\n",
14         getpid(), getppid());
15 }

$ fork0
[18607] parent process id: 18606

        [18608] parent process id: 18607

        [18607] parent process id: 18606