首页 文章

fork():[保留]创建的子进程数

提问于
浏览
-2
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main() 
{ 
  int pid =  fork(); 
  for(int i=0;i<5;i++)
  {  
    if(pid == 0)
    {
        fork();
        printf("fork\n");
    } 
  }    
return 0; 
}

我认为它应该产生总共6个子进程 . 但事实并非如此 . 为什么

1 回答

  • 3

    解释

    fork() 创建了一个重复的进程,该进程继续运行与父进程并行调用的代码 . 在父fork()中返回子PID,在子中它返回零 - 除了新进程相同但是彼此的副本 - 将变量设置为一个不会影响另一个 .

    通常在 fork() 之后,您检查其返回以查看您的程序副本是儿童还是父母,并采取相应行动 .

    更正了代码

    所以,如果你的目标是创建6个子进程(加上一个父进程),你应该做这样的事情:

    #include <stdio.h> 
    #include <sys/types.h> 
    #include <unistd.h> 
    int main() 
    { 
    
      printf("Hello from parent, my PID is %d\n", getpid());
      for(int i=0;i<6;i++)
      {  
        int pid = fork(); 
        if (pid == 0)
        {
           printf("Hello from child, my PID is %d\n", getpid());
           return 0;
        }
        printf("Parent created child with PID=%d\n", pid);
      }    
    return 0; 
    }
    

    并且我系统上的输出是:

    Hello from parent, my PID is 26354
    Parent created child with PID=26355
    Hello from child, my PID is 26355
    Parent created child with PID=26356
    Parent created child with PID=26357
    Parent created child with PID=26358
    Hello from child, my PID is 26356
    Parent created child with PID=26359
    Parent created child with PID=26360
    Hello from child, my PID is 26357
    Hello from child, my PID is 26358
    Hello from child, my PID is 26359
    Hello from child, my PID is 26360
    

    请注意,每个孩子打印出 Hello from child... 消息,然后立即退出 returnmain() .

    错误

    • 你的代码检查错误,因此衍生的孩子不仅仅是退出 - 他们继续创造更多自己的孩子,他们的孩子继续做同样的事情 .

    • 您应该每次都分配 pid = fork() ,而不仅仅是第一次 .

    • 如果您的孩子已经完成,建议立即通过调用_46927来让它退出,而不是让它继续循环您的程序并将其中的部分包装在 if (pid==0) 中 - 这可能会导致进一步的错误

    • 你的父亲创建第一个孩子(在循环之前)并收到非零 pid 所以它仍然经历后续循环但没有做任何其他事情 - 第一个孩子完成所有工作 .

    • 此外,每次调用 fork\n 时都会打印 fork\n ,因为父项和子项都是在每个孩子(第一个"before-the-loop"除外)之后创建的 - 可能不是你想要的 .

    代码分析

    让我们看看代码的作用 .

    我将任意编号进程,进程#0是原始父进程 .

    int pid =  fork();
    

    进程#0创建进程#1 . 在子(#1) pid = 0 中,在父(#0)中,它不为零 .

    因为以下代码检查 pid0

    if(pid == 0)
    {
        fork();
        printf("fork\n");
    }
    

    ...进程#0循环5次但什么都不做,什么也没打印出来并最终退出 .

    因为 pid 不再被写入并且未被检查,因此对于进程#1和所有后续进程,此循环如下所示:

    for(int i=0;i<5;i++)
    {  
          fork();
          printf("fork\n");
    }    
    return 0;
    

    以下并行发生,排序是任意的:

    • 现在进程#1创建了五个子节点 - #2,#3,#4,#5,#6,每次打印 fork\n ,最终退出 .

    • 进程#2启动进程#1停止创建它,使用 i=0 ,就在 printf 之前,因此它打印出 fork\n 并继续打印4次消息并创建4个自己的子进程(#7,#8, #9,#10)并最终退出

    • 进程#3启动进程#1停止创建它,使用 i=1 ,就在 printf 之前,因此它打印出 fork\n 并继续创建3个自己的子进程,再打印3次消息(#11,#12, #13)并最终退出

    • 进程#4创建2个进程(#14,#15),打印3条消息

    • 进程#5创建1个进程(#16),打印2条消息

    • 进程#6与 i=4 保持关闭,因此它打印出一条消息并退出 .

    • 进程#7(由第二个子进程创建)与进程#3保持相同的状态,因此它会打印消息4次并创建3个自己的子进程...

    ......此时我可能会停下来,你应该已经知道这是怎么回事了 .

    这是我添加一些日志记录后程序的输出 . 我还对输出进行了一些排序 - 因为它全部并行发生,否则很难跟踪:

    Process 27939 is the original parent
    Process 27939 created process 27940 <--- this is the 'out-of-loop' child
    Process 27939 finished executing
    Process 27940 created process 27942
    Process 27940: fork
    Process 27940 created process 27943
    Process 27940: fork
    Process 27940 created process 27944
    Process 27940: fork
    Process 27940 created process 27945
    Process 27940: fork
    Process 27940 created process 27946
    Process 27940: fork
    Process 27940 finished executing
    Process 27942: fork
    Process 27942 created process 27954
    Process 27942: fork
    Process 27942 created process 27955
    Process 27942: fork
    Process 27942 created process 27956
    Process 27942: fork
    Process 27942 created process 27957
    Process 27942: fork
    Process 27942 finished executing
    Process 27943: fork
    Process 27943 created process 27958
    Process 27943: fork
    Process 27943 created process 27959
    Process 27943: fork
    Process 27943 created process 27960
    Process 27943: fork
    Process 27943 finished executing
    Process 27944: fork
    Process 27944 created process 27961
    Process 27944: fork
    Process 27944 created process 27962
    Process 27944: fork
    Process 27944 finished executing
    Process 27945: fork
    Process 27945 created process 27963
    Process 27945: fork
    Process 27945 finished executing
    Process 27946: fork
    Process 27946 finished executing
    Process 27954: fork
    Process 27954 created process 27970
    Process 27954: fork
    Process 27954 created process 27971
    Process 27954: fork
    Process 27954 created process 27972
    Process 27954: fork
    Process 27954 finished executing
    Process 27955: fork
    Process 27955 created process 27978
    Process 27955: fork
    Process 27955 created process 27979
    Process 27955: fork
    Process 27955 finished executing
    Process 27956: fork
    Process 27956 created process 27981
    Process 27956: fork
    Process 27956 finished executing
    Process 27957: fork
    Process 27957 finished executing
    Process 27958: fork
    Process 27958 created process 27980
    Process 27958: fork
    Process 27958 created process 27982
    Process 27958: fork
    Process 27958 finished executing
    Process 27959: fork
    Process 27959 created process 27983
    Process 27959: fork
    Process 27959 finished executing
    Process 27960: fork
    Process 27960 finished executing
    Process 27961: fork
    Process 27961 created process 27984
    Process 27961: fork
    Process 27961 finished executing
    Process 27962: fork
    Process 27962 finished executing
    Process 27963: fork
    Process 27963 finished executing
    Process 27970: fork
    Process 27970 created process 28002
    Process 27970: fork
    Process 27970 created process 28003
    Process 27970: fork
    Process 27970 finished executing
    Process 27971: fork
    Process 27971 created process 28004
    Process 27971: fork
    Process 27971 finished executing
    Process 27972: fork
    Process 27972 finished executing
    Process 27978: fork
    Process 27978 created process 28006
    Process 27978: fork
    Process 27978 finished executing
    Process 27979: fork
    Process 27979 finished executing
    Process 27980: fork
    Process 27980 created process 28008
    Process 27980: fork
    Process 27980 finished executing
    Process 27981: fork
    Process 27981 finished executing
    Process 27982: fork
    Process 27982 finished executing
    Process 27983: fork
    Process 27983 finished executing
    Process 27984: fork
    Process 27984 finished executing
    Process 28002: fork
    Process 28002 created process 28043
    Process 28002: fork
    Process 28002 finished executing
    Process 28003: fork
    Process 28003 finished executing
    Process 28004: fork
    Process 28004 finished executing
    Process 28006: fork
    Process 28006 finished executing
    Process 28008: fork
    Process 28008 finished executing
    Process 28043: fork
    Process 28043 finished executing
    

相关问题