为什么在使用fork系统调用时打印了很多PID?

我正在学习Linux中的进程管理,我尝试实现以下C程序,其输出打印了15个PID(4个唯一的PID)。 我试图找出进程族树,但它确实没有帮助我理解为什么PID被打印了这么多次。 我浏览了几个链接,包括http://u.cs.biu.ac.il/~linraz/os/OS2.pdf,http://www.ibm.com/developerworks/aix/library/au-unixprocess.html , 谁在fork()之后首先执行:父或孩子? 。 但是,我找不到解决方案。 如果有人帮助我理解这个问题,那将会很有帮助。

#include  #include  #include  int main() { printf ( "Parent:%d Child: %d\n",getppid(),getpid()); // To print the PIDs of the parent process and the child process fork(); //System call to spawn a child process printf ( "Parent:%d Child: %d\n",getppid(),getpid()); fork(); printf ( "Parent:%d Child: %d\n",getppid(),getpid()); fork(); printf ( "Parent:%d Child: %d\n",getppid(),getpid()); return 0; } 

启动程序时,内核会为其分配PID。 PPID是启动程序的进程的PID,通常是你的shell。 出于本答案的目的,我们将为您的shell分配PID为123 ,并且您的程序在开始时将被分配130的pid。

第一行输出将只显示PPID和PID。

 Parent:123 Child: 130 

该计划所做的下一件事就是分成两部分。 原始程序的PID和PPID保持不变,子程序的PPID是原始程序的PID,子项被分配了新的PID。 由于两个程序仍然绑定到相同的输出通道,因此可以首先显示任一输出。 为简单起见,我们假装输出是有序的。

 Parent:123 Child: 130 Parent:130 Child: 131 

现在你第二次分叉…… 两个过程都是自己复制的。 您现在有四个进程要将输出打印到同一个通道。

 Parent:123 Child: 130 Parent:130 Child: 131 Parent:130 Child: 132 Parent:131 Child: 133 

现在,使用您的第三个fork,所有这四个进程再次重复。

 Parent:123 Child: 130 Parent:130 Child: 131 Parent:130 Child: 132 Parent:131 Child: 133 Parent:130 Child: 134 Parent:131 Child: 135 Parent:132 Child: 136 Parent:133 Child: 137 

任何问题?

fork()通过复制调用进程来创建一个新进程。 新进程(称为子进程)与调用进程完全相同,称为父进程。

 A fork() |----------------B | | |fork() | |----C | | | | 

如果您调用fork(),则子进程和父进程将执行下一条指令

你的程序看起来像这样

  printf ("Hi"); //prints only one time fork(); printf ("Hi"); //prints two times fork(); printf ("Hi"); //prints four times 

考虑所有fork()创建的子进程成功。

  printf ("Hi"); fork();------------------------------------------------| | | printf ("Hi"); printf ("Hi"); fork();----------------| fork();---------------| printf ("Hi"); printf ("Hi"); printf ("Hi"); printf ("Hi"); 

每次调用fork时,都会复制当前进程。 所以第一个printf执行一次 – 只有一个进程。 然后调用fork()使第二个printf执行两次 – 在父进程上执行一次,在新子进程上执行一次。 然后父母和孩子每个fork创建4个进程总计等等…

fork ,会创建一个新进程,但父进程也会继续执行。 所以你的main执行所有4个打印,你的第一个fork将执行随后的3个打印,依此类推。 要控制每个子节点和父节点将执行的代码,您必须使用fork返回值,而不仅仅是fork。