循环外的fork()
调用很容易弄清楚,但是当它们在循环内时,我发现很难。谁能用这样的例子来形象地解释这些过程是如何分支的?
#include <stdio.h>
int main(){
int i;
for(i=0;i<2;i++)
{
fork();
printf("hi");
fork();
}
exit(0);
}
理想情况下,情况如下:
- 每个进程都印有一个"hi"(缩写为 proc) 每个
- 分叉使进程数增加一倍(每个进程生成一个子进程)
可以通过跟踪每个事件来完成计算:
- 开始:1 个进程
- 分叉:2 x 1 = 2 个进程
- 打印:2 个进程 -> 个 2 个 HI
- 分叉:2 x 2 = 4 个进程
- 分叉:2 x 4 = 8 个进程
- 打印:8 个进程 -> 8 个 HI
- 叉子:2 x 8 个进程 -> 16 个进程
现在我们将 hi 的数量相加:
总共 2 + 8 = 10 个 hi
但是,情况并不一定如此。在不同的系统上,您可能会得到不同的结果。
对 fork() 的调用会导致生成与父进程相同的子进程。如果在打印标准输出时进行了任何缓冲,并且在下一个分叉之前没有刷新缓冲区,那么子节点将在"不应该"打印时出现打印。有关缓冲的一些详细信息,请参阅此问题。
这会导致不同的系统打印不同数量的 hi。
只需展开循环:
int main() {
int i;
fork();
printf("hi");
fork();
fork();
printf("hi");
fork();
exit(0);
}
我使用了这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int i;
for(i=0;i<2;i++)
{
fork();
printf("hi from pid %dn",getpid());
fork();
}
exit(0);
}
现在我已经通过管道将输出传输到 fk.out。
[aft@kruki sf]$ cat fk.out
hi from pid 6698
hi from pid 6698
hi from pid 6699
.......................
现在看看这个:
[aft@kruki sf]$ cat fk.out | awk '{print $4}' | sort | uniq | wc -l
8
在那里,你有它,你有 8 个进程!不要打招呼。因为 stdin 缓冲区会来回切换,所以计算 hi 会模棱两可。