【问题标题】:How do processes branch out when you use fork() in a for loop?在 for 循环中使用 fork() 时,进程如何分支?
【发布时间】:2012-08-08 03:11:54
【问题描述】:

fork() 循环外的调用很容易弄清楚,但是当它们在循环内时,我觉得很难。谁能用这样一个例子来形象地解释流程是如何分支的?

#include <stdio.h>

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

【问题讨论】:

    标签: c unix operating-system fork


    【解决方案1】:

    只需展开循环:

    int main() {
        int i;
        fork();
        printf("hi");
        fork();
        fork();
        printf("hi");
        fork();
        exit(0);
    }
    

    【讨论】:

    • 没有。不是这样的,按照你的解释,肯定有16个“嗨”,但实际上只有6个......
    • 有12个ideone.com/bUNDZ注意循环中第二个fork后有printf
    • 我看到不一致的结果 ideone.com/QMesr ideone.com/gXVxW。是否会在子进程到达打印之前杀死它们的退出(0)?
    • 实际上,“hi”被打印了 32 次,如果将输出重定向到文件,这更容易看出。如果这样做,您可能还会看到一些空字节。我怀疑在分叉之后调用printf 并不完全安全(请参阅man printf 末尾的警告)。有趣的是,如果我将输出传送到hexdump,我看不到空字节。
    • 我在每个 printf 之后添加了 fflush(0),现在得到了预期的 10 次打印
    【解决方案2】:

    理想情况下是这样的:

    • 每个进程都印有一个“hi”(简称proc)
    • 每个 fork 使进程数量翻倍(每个进程产生一个子进程)

    可以按照每个事件进行计算:

    • 开始:1 个过程
    • 分叉:2 x 1 = 2 触发
    • print: 2 procs -> 2 hi's
    • 分叉:2 x 2 = 4 触发
    • 分叉:2 x 4 = 8 触发
    • print: 8 procs -> 8 hi's
    • fork:2 x 8 触发 -> 16 触发

    现在我们将 hi 的数量相加:

    2 + 8 = 总共 10 个嗨

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

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

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

    【讨论】:

      【解决方案3】:

      我用过这段代码:

      #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 个进程!。不要指望你好。因为 stdin 缓冲区会来回切换,所以计算 hi 会很模糊。

      【讨论】:

        猜你喜欢
        • 2013-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-29
        • 2020-07-18
        • 2014-08-06
        相关资源
        最近更新 更多