Понимание того, как UNIX fork () влияет на родительский процесс - PullRequest
0 голосов
/ 02 октября 2018

У меня есть следующая программа, которая использует функцию fork () для создания дочерних процессов

#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork();
   fork();
   fork();
   printf ("Done"); //print2:P2
}

Я пытаюсь понять, как вышеприведенная программа печатает «Done» 8 раз из-за этого вывода.

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Обратите внимание, что каждый последующий форк будет выполняться дочерними элементами, созданными ранее.Таким образом, иерархия процессов будет выглядеть следующим образом:

Parent
  -- Child 1                   (first fork executed by Parent)
     -- Grandchild 1           (second fork executed by Child 1)
        -- Grand-grandchild 1  (third fork executed by Grandchild 1)
     -- Grandchild 2           (third fork executed by Child 1)
  -- Child 2                   (second fork executed by Parent)
     -- Grandchild 3           (third fork executed by Child 2)
  -- Child 3                   (third fork executed by Parent)

И каждый из них вызовет printf ("Done");.8 всего.

0 голосов
/ 02 октября 2018

Я сделаю это немного более наглядным:

Шаг 1

// Program 1
#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork(); // <- Current Line
   fork();
   fork();
   printf ("Done"); //print2:P2
}

Шаг 2

Когда эта строка выполняется, она разбивается на две программы:

// Program 1                                                   >----|
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork(); // Returns child's PID [Program 1 Version 2]             |
   fork(); // <- Current line                                       |
   fork();                                                          |
   printf ("Done"); //print2:P2                                     |
}                                                                   |
                                                                    |
// Program 1 Version 2 (Child of Program 1)   >----|                |
#include <stdio.h>                                 |                |
   int main (){                                    |                |
   printf("PID:%d\n",getpid());//print1:P1         |                |
   fork(); // Returns 0, since it's a child        |                |
   fork(); // <- Current line                      |                |
   fork();                                         |                |
   printf ("Done"); //print2:P2                    |                |
}                                                  |                |

Шаг 3

Когда программа 1 версии 2 выполняет свою текущую строку, она создает

// Program 1 Version 2                       <-----|                |
#include <stdio.h>                                 |                |
   int main (){                                    |                |
   printf("PID:%d\n",getpid());//print1:P1         |                |
   fork();                                         |                |
   fork(); // Returns child's PID [Program 1 Version 2] Version 2   |
   fork(); // <- Current line                      |                |
   printf ("Done"); //print2:P2                    |                |
}                                                  |                |
                                              v----|                |
// [Program 1 Version 2] Version 2 (Child of Program 1 Version 2)   |
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork();                                                          |
   fork(); // Returns 0 (It's a new child)                          |
   fork(); // <- Current line                                       |
   printf ("Done"); //print2:P2                                     |
}                                                                   |

Когда программа 1 выполняет свою текущую строку, она создает

// Program 1                                           <------------|
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork();                                                          |
   fork(); // Returns child's PID [Program 1 Version 3]             |
   fork(); // <- Current line                                       |
   printf ("Done"); //print2:P2                                     |
}                                                                   |
                                                                    |
// Program 1 Version 3 (Child of Program 1)             <-----------|
#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork();
   fork(); // Returns 0 (Is a new child)
   fork(); // <- Current line
   printf ("Done"); //print2:P2
}

Шаг 4

Каждая из последних вилок снова дублирует каждую программу, в результате чего у вас работает 8 программ.Каждая оригинальная программа получает PID ребенка, возвращаемый fork.Каждая дочерняя программа получает 0. Затем все они printf("Done")

Примечание

После того, как программа сгенерирована, она просто запускает все вилки и получает кучу PID, а затем печатает.Просто так получается, что каждая ветвь делает ребенка дочерним, но родитель этого не замечает, и они в основном НЕТ-ОП для родителя.

0 голосов
/ 02 октября 2018

Когда процесс создается с помощью вызова fork(), как

 fork();

После fork() любых операторов, когда они выполняются дочерним и один раз родительским процессом.В вашем случае fork() называется трижды, поэтому печатается 8 раз Done.Это выглядит как

fork();
printf ("Done\n"); /* once printed by child process & once by parent process, so for one fork() call, it prints 2 times Done. For 3 fork call, 8 times */

На странице руководства fork()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...