简体   繁体   English

了解UNIX fork()如何影响父进程

[英]Understanding how UNIX fork() affects parent process

I have the following program that uses the fork() function to create child processes 我有以下使用fork()函数创建子进程的程序

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

I am trying to understand how does the above program prints 'Done' 8 times because that the output. 我试图了解上述程序如何打印“完成” 8次,因为该输出。

You should note that each subsequent fork will get executed by children that created before. 您应注意,每个后续派生将由之前创建的子代执行。 So the process hierarchy will be as follows: 因此,流程层次结构如下:

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)

And each of these will call printf ("Done"); 每个都将调用printf ("Done"); . 8 in total. 总共8个。

When a process is created by calling fork() like 通过调用fork()创建进程时

 fork();

After fork() whatever statements are there, once they executed by child & once by parent process. fork()无论语句是由子进程执行还是由父进程执行,它们都存在。 In your case fork() is called thrice hence it print 8 times Done . 在您的情况下, fork()称为三次,因此它打印8次Done It looks like 看起来像

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 */

From the manual page of fork() fork()的手册页

fork() creates a new process by duplicating the calling process . fork()通过复制 调用进程创建一个 进程 The new process, referred to as the child, is an exact duplicate of the calling process 新进程称为子进程,它与调用进程完全相同

I'll make it a bit more visual: 我将使其更加直观:

Step 1 第1步

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

Step 2 第2步

When this line executes, it splits into two programs: 执行此行后,它将分为两个程序:

// 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                    |                |
}                                                  |                |

Step 3 第三步

When Program 1 Version 2 executes its current line, it creates 当程序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                                     |
}                                                                   |

When Program 1 executes its current line, it creates 程序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
}

Step 4 第四步

Each of the final forks again duplicates each program, leaving you with 8 programs running. 每个最终分支都将重复每个程序,从而使您有8个程序在运行。 Each original program gets the child's PID as returned by fork. 每个原始程序都会获取派生返回的孩子的PID。 Each child program gets 0. Then they all printf("Done") 每个子程序都得到0。然后它们全部用printf("Done")

Note 注意

Once a program is generated, it just runs all the forks and gets a bunch of PIDs, then prints done. 生成程序后,它将仅运行所有fork,并获取一堆PID,然后完成打印。 It just happens that each fork makes a child, but the parent doesn't notice and they're basically NO-OPs for the parent. 碰巧每个叉子都生了一个孩子,但父母却没有注意到,而且对于父母来说,它们基本上是无条件的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM