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