麻烦理解c中的fork()

时间:2016-05-02 15:26:04

标签: c

我知道fork()会创建一个孩子,而for loop会为每个孩子重复fork()。但我不知道为什么我会让7个孩子的过程重复3次。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
    int i;
    printf("Process PID %6d \t PPID %6d \n",
    getpid(), getppid());
    for (i = 0; i<3; ++i)
    {
        if (fork()==0)
        printf("Process PID %6d \t PPID %6d \n", getpid(), getppid()); 
    }
    return 0;
}

任何人都可以解释这个编码

3 个答案:

答案 0 :(得分:8)

让我画一个树形图。

parent i=0
fork() -------------------------------------v
parent i=1                                  child1 i=1
fork() ---------------v                     fork() ---------------v
parent i=2            child2 i=2            child1 i=2            child2 i=2
fork() ----v          fork() ----v          fork() ----v          fork() ----v
parent i=3 child3 i=3 child2 i=3 child3 i=3 child1 i=3 child3 i=3 child2 i=3 child3 i=3
           1          2          3          4          5          6          7

因此创造了7个孩子。

答案 1 :(得分:3)

让我们来看看这些步骤: (请注意,步骤的顺序不是一成不变的(孩子可以在父亲再次分叉之前进行分叉),但这并没有改变因果关系,所以我只假设一个任意顺序,使其更容易解释)

  • 首先,您有一个流程(让我们称之为流程#42)
  • 它分叉:你现在有两个进程,它们都完成了第一次迭代:
    • 过程#42,过去第一次迭代
    • 让我们称之为过程#43,#42的儿子,过去的第一次迭代
  • 进程#42进行第二次迭代并再次分叉:您现在有三个进程:
    • 流程#42,过去第二次迭代
    • 过程#43,#42的儿子,经过第一次迭代
    • 过程#44,#42的儿子,过去第二次迭代
  • 进程#42进行第三次迭代并最后一次分叉:现在有四个进程:
    • 流程#42,过去第三次迭代
    • 过程#43,#42的儿子,经过第一次迭代
    • 过程#44,#42的儿子,过去第二次迭代
    • 过程#45,#42的儿子,过去的第三次迭代(不会分叉)
  • 现在#42流程完成了分叉,让我们看看它的儿子会发生什么:
  • 进程#43进行第二次迭代并再次分叉#34; (实际上它是第一次,但它只会分叉两次):你现在有五个进程:
    • 流程#42,过去第三次迭代
    • 过程#43,#42的儿子,过去第二次迭代
    • 过程#44,#42的儿子,过去第二次迭代
    • 过程#45,#42的儿子,过去的第三次迭代(不会分叉)
    • 过程#46,#43的儿子,过去第二次迭代
  • 进程#43进行第三次迭代并最后一次分叉:您现在有六个进程:
    • 流程#42,过去第三次迭代
    • 过程#43,#42的儿子,过去的第三次迭代
    • 过程#44,#42的儿子,过去第二次迭代
    • 过程#45,#42的儿子,过去的第三次迭代(不会分叉)
    • 过程#46,#43的儿子,过去第二次迭代
    • 过程#47,#43的儿子,过去的第三次迭代(不会分叉)
  • 进程#44进行第三次迭代并首先分叉一次:你现在有七个进程:
    • 流程#42,过去第三次迭代
    • 过程#43,#42的儿子,过去的第三次迭代
    • 过程#44,#42的儿子,过去的第三次迭代
    • 过程#45,#42的儿子,过去的第三次迭代(不会分叉)
    • 过程#46,#43的儿子,过去第二次迭代
    • 过程#47,#43的儿子,过去的第三次迭代(不会分叉)
    • 过程#48,#44的儿子,过去的第三次迭代(不会分叉)
  • 最后,Process#46进行了第三次迭代,并且也是第一次和最后一次分叉。你现在应该有八个进程,其中七个是子进程:
    • 流程#42,过去第三次迭代
    • 过程#43,#42的儿子,过去的第三次迭代
    • 过程#44,#42的儿子,过去的第三次迭代
    • 过程#45,#42的儿子,过去的第三次迭代(不会分叉)
    • 过程#46,#43的儿子,过去的第三次迭代
    • 过程#47,#43的儿子,过去的第三次迭代(不会分叉)
    • 过程#48,#44的儿子,过去的第三次迭代(不会分叉)
    • 过程#49,#46的儿子,过去的第三次迭代(不会分叉)

总共有八个进程,其中七个是孩子,其中四个根本没有分叉。

答案 2 :(得分:0)

非常简化:

其中=>表示fork

parent => (child-1), (child-2), (child-3)
           child-1 => (child-11), (child-12)
                       child-11 => (child-111)
                      child-2 => (child-21)