#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 回答
解释
fork()
创建了一个重复的进程,该进程继续运行与父进程并行调用的代码 . 在父fork()中返回子PID,在子中它返回零 - 除了新进程相同但是彼此的副本 - 将变量设置为一个不会影响另一个 .通常在
fork()
之后,您检查其返回以查看您的程序副本是儿童还是父母,并采取相应行动 .更正了代码
所以,如果你的目标是创建6个子进程(加上一个父进程),你应该做这样的事情:
并且我系统上的输出是:
请注意,每个孩子打印出
Hello from child...
消息,然后立即退出return
从main()
.错误
你的代码检查错误,因此衍生的孩子不仅仅是退出 - 他们继续创造更多自己的孩子,他们的孩子继续做同样的事情 .
您应该每次都分配
pid = fork()
,而不仅仅是第一次 .如果您的孩子已经完成,建议立即通过调用_46927来让它退出,而不是让它继续循环您的程序并将其中的部分包装在
if (pid==0)
中 - 这可能会导致进一步的错误你的父亲创建第一个孩子(在循环之前)并收到非零
pid
所以它仍然经历后续循环但没有做任何其他事情 - 第一个孩子完成所有工作 .此外,每次调用
fork\n
时都会打印fork\n
,因为父项和子项都是在每个孩子(第一个"before-the-loop"除外)之后创建的 - 可能不是你想要的 .代码分析
让我们看看代码的作用 .
我将任意编号进程,进程#0是原始父进程 .
进程#0创建进程#1 . 在子(#1)
pid = 0
中,在父(#0)中,它不为零 .因为以下代码检查
pid
是0
:...进程#0循环5次但什么都不做,什么也没打印出来并最终退出 .
因为
pid
不再被写入并且未被检查,因此对于进程#1和所有后续进程,此循环如下所示:以下并行发生,排序是任意的:
现在进程#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个自己的子进程...
......此时我可能会停下来,你应该已经知道这是怎么回事了 .
这是我添加一些日志记录后程序的输出 . 我还对输出进行了一些排序 - 因为它全部并行发生,否则很难跟踪: