-2

fork()循环外的调用很容易弄清楚,但是当它们在循环内时,我发现很难。任何人都可以用这样一个例子来形象地解释流程是如何分支的吗?

#include <stdio.h>

int main(){
    int i; 
    for(i=0;i<2;i++)
    {
        fork();
        printf("hi");
        fork();
    }
    exit(0);
}
4

3 回答 3

2

理想情况下,情况会是这样:

  • 每个进程打印一个“hi”(简写为proc)
  • 每个分叉使进程数量翻倍(每个进程产生一个子进程)

可以通过跟踪每个事件来完成计算:

  • 开始:1个过程
  • 分叉:2 x 1 = 2 个过程
  • 打印:2 procs -> 2 hi
  • 分叉:2 x 2 = 4 个过程
  • 分叉:2 x 4 = 8 触发
  • 打印:8 procs -> 8 hi
  • 分叉:2 x 8 触发 -> 16 触发

现在我们把hi的数量加起来:

2 + 8 = 10 个 hi

但是,情况不一定如此。在不同的系统上,您可能会得到不同的结果。

调用 fork() 会产生一个与父进程相同的子进程。如果在打印 stdout 时完成了任何缓冲,并且在下一次分叉之前没有刷新缓冲区,那么孩子将在“不应该”时出现打印。有关缓冲的一些详细信息,请参阅问题。

这会导致在不同的系统中打印不同数量的 hi。

于 2012-08-10T20:48:06.353 回答
1

只需展开循环:

int main() {
    int i;
    fork();
    printf("hi");
    fork();
    fork();
    printf("hi");
    fork();
    exit(0);
}
于 2012-08-10T19:33:01.630 回答
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 %d\n",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 个进程!不要指望你好。因为标准输入缓冲区会来回切换,所以计算 hi 将是模棱两可的。

于 2012-08-10T20:58:35.400 回答