Как работает fork (), когда дочерние fork - PullRequest
3 голосов
/ 30 сентября 2011

Я выполнил блок кода. И это так, как показано ниже:

#include<stdio.h>

main() {
int i=0;
fork();
printf("The value of i is:%d\n",++i);
fork();
printf("The value of j is:%d\n",++i);
fork();
wait();
}

И я получил следующий вывод:

The value of i is:1
The value of j is:2
The value of i is:1
The value of j is:2
The value of j is:2
pckoders@ubuntu:~$ The value of j is:2

Может кто-нибудь объяснить мне, какую роль здесь играют функции fork () и wait ()?

Ответы [ 4 ]

11 голосов
/ 30 сентября 2011

fork() колл буквально форк.После его завершения у вас есть 2 точных процесса с точным стеком, и все дескрипторы ссылаются на одни и те же объекты.Вы можете различить их по возвращаемому значению.Для дочернего процесса fork() возвращает 0, для родителя - идентификатор дочернего процесса.

так

main() {
int i=0;
fork(); 
// at this point you are having 2 processes. stdout and stdin are basically just dupplicates.
//          (P)
//        /     \
//     (P)       (C)
//   prints1    prints 1
printf("The value of i is:%d\n",++i); // so 2 processes with print 1
fork();
// now you are having 4 processes( both parent and children forked)
//                   (P)
//                 /     \
//               /         \
//           (P)            (C)
//         /     \         /   \
//      (PP)     (PC)    (CP)  (CC)
//   prints 2  prints 2  prints 2  prints 2
printf("The value of j is:%d\n",++i);
fork();
// now 4 processes are forking. now you have 8 processes
//                                   (P)
//                                /       \
//                            /              \
//                         /                    \
//                   (P)                           (C)             
//                 /     \                       /     \           
//               /         \                   /         \          
//          (PP)           (PC)             (CP)          (CC) 
//         /     \        /     \          /    \       /     \        
//     (PPP)    (PPC)  (PCP)   (PCC)   (CPP)   (CPC)  (CCP)  (CCC)   

wait();
}
6 голосов
/ 30 сентября 2011

Программа генерирует дерево процессов.На каждом fork это дерево ветвится надвое.Если вы возьмете лист бумаги, нарисовать это дерево не очень сложно;единственное, что трудно, это получить правильные значения i из-за использования префикса ++.Если вы позволите каждому процессу sleep в течение нескольких секунд в конце, вы также можете наблюдать дерево, используя программу pstree.

Каждый из процессов затем выполняет системный вызов wait, который ожидает завершения любого из его дочерних процессов (дочерних узлов в дереве процессов).

1 голос
/ 30 сентября 2011

После первого fork () было два процесса (текущий и его точный экземпляр, дочерний элемент), которые оба напечатали 1.

Каждый из этих двух процессов дублировался во втором вызове fork (), и было 4 процесса, каждый из которых напечатал 2.

Их вывод происходит в случайном порядке, как это всегда происходит при параллельном выполнении.

0 голосов
/ 09 сентября 2012

Процессы Forking создают дочерние элементы в древовидной форме. Рассматривайте каждый форк как разные слои двоичного дерева. Когда вы не запускаете fork (), у вас есть дерево процессов только с корневым узлом. один fork (), тогда у вас теперь есть двоичное дерево с двумя уровнями, первый уровень будет содержать родительский процесс, второй уровень будет содержать два процесса - родительский и дочерний процесс.

Когда вы хотите узнать количество процессов, которые у вас под рукой, просто продолжайте строить двоичное дерево / дерево процессов и посмотрите, сколько узлов существует на последнем уровне, последний уровень - это не что иное, как текущее состояние процесса / Функция tree.Wait заставляет вашего родителя ждать завершения дочернего процесса. В приложениях, где вам не нужен процесс зомби, вам нужно подождать, иначе эти процессы зомби будут продолжать перегружать систему ... ссылка .

Помните, что ожидание также полезно, когда вы всегда хотите, чтобы родитель закончил после ребенка. Форкинг не всегда дает один и тот же результат, порядок перемешан, поэтому, чтобы получить один и тот же результат всегда, используйте wait (). Чтобы дождаться определенного дочернего процесса, используйте wait (pid), где pid - это pid определенного дочернего процесса, и этот pid можно получить с помощью getpid внутри пространства дочернего процесса.

...