Если родительский процесс дочернего процесса завершается или умирает раньше дочернего процесса, то дочерний процесс называется осиротевшим процессом и принимается init
.Это означает, что PPID (родительский PID) ребенка изменится на 1. Это объясняет ваш вывод, так как он приходит от getppid()
.
Чтобы объяснить количество отображаемых строк, нумеруем строки кода:
1 int p,m;
2 p = getppid();
3 printf("%d\n",p);
4
5 if(fork() == 0) {
6 p = getppid();
7 printf("%d\n",p);
8 }
9
10 if(fork() == 0) {
11 p = getppid();
12 printf("%d\n",p);
13 }
14
15 if(fork() == 0) {
16 p = getppid();
17 printf("%d\n",p);
18 }
19
20 if(fork() == 0) {
21 p = getppid();
22 printf("%d\n",p);
23 }
Теперь давайте посчитаем все процессы, которые выполняли каждый printf()
.printf()
в строке 3, очевидно, был выполнен только исходным родительским процессом.printf()
в строке 7 был выполнен только первым потомком исходного родительского процесса, поскольку fork()
возвращает 0 в потомке.Теперь строка 9 достигается двумя процессами: исходным родителем и его первым потомком.Оба они fork и оба их потомка (то есть второй потомок исходного родителя и первый потомок первого потомка исходного родителя) выполняют printf()
в строке 12. Строка 14 достигается 4 процессами (исходный родитель, его оба потомка и первый потомок первого потомка первоначального родителя).Все они порождают детей в строке 15, и все четверо детей выполняют printf()
в строке 17. Целых 8 процессов достигают строки 19. Каждый из них разветвляется, и 8 детей в младшем поколении выполняют финальный printf()
в строке 22.
Первый printf()
выполняется 1 раз.Секунда printf()
выполняется 1 раз.Третий printf()
выполняется 2 раза.Четвертый printf()
выполняется 4 раза.Пятый printf()
выполняется 8 раз.
Это всего 16 и соответствует вашему выводу.Некоторые из отображаемых PPID равны 1, что указывает на то, что данный родитель выполнялся настолько быстро, что ребенок был усыновлен init до того, как он достиг printf()
.Остальные больше 1, что указывает на то, что родительский процесс данного процесса все еще работал, когда в дочернем элементе был достигнут printf()
.Весьма вероятно, что многократное выполнение программы приведет к несколько другому выводу.
Таким образом, вы создаете не 4 дочерних процесса, а 15. Это связано с тем, что ваши дети продолжают выполнять с того момента, когдаfork()
, который породил их, возвращается.Это означает, что некоторые из fork()
будут выполняться не только исходным родителем, но и его потомками, создавая каскад новых процессов.Если вы хотите создать только 4 дочерних элементов, вы должны убедиться, что оставшийся разветвление происходит только в родительском элементе.