叉概念,不太明白叉如何工作

时间:2013-11-25 07:51:23

标签: c fork concept

我尝试根据代码绘制过程,但我真的需要解释原因,这里是问题:

B() {
     pid_t pid;
     if ((pid = fork()) != 0)
         waitpid(pid,NULL,0);
     printf("2");
     if(fork() ==0)
       { printf("3"); exit(0); }
     printf("5");
     exit(0);
}

Which one are illegals output?
232553, 235325, 232355, 235253, 252533...

这是我根据代码和我对fork的理解而绘制的过程。

            ___3 (exit so no more here)
           |
      __2__|___5 (I guess 5 should be here)
     |          |        
     |          |
 ____|____(wait)|(start again since printf 3 process end)

所以我被困在那里......感谢任何帮助。

5 个答案:

答案 0 :(得分:3)

好的,有两个叉子。这是从左到右的控制流程,父母在顶部,孩子在底部:

    +-- B ---- waitpid() --+                  +-- "5" -- E
    |                      |                  |
A --+ fork()               +-- C -- "2" -- D -+ fork()
    |                      |                  |
    +----------------------+                  +-- "3" -- F

那么,我们知道什么?

  • “2”,“5”和“3”各出现两次(90种可能性)

  • 没有前缀可能包含比“2”更多的“3”(30种可能性)

  • 没有前缀可能包含比“2”更多的“5”(16种可能性)

  • 第二个“2”必须以第一个“5”开头(7种可能性)

7种可能性是:

2,3,5,2,3,5
2,3,5,2,5,3
2,5,2,3,3,5
2,5,2,3,5,3
2,5,2,5,3,3
2,5,3,2,3,5
2,5,3,2,5,3

答案 1 :(得分:2)

这应该是程序路径(x表示终止):

---+--(wait)-2-+-5-x
   |           |
   +-2-+-5-x   +-3-x
       |   
       +-*3-x

在第一个fork之后,父母等待孩子完成。但是在第二个fork的情况下,它不会等待。因此,*标记为3可以在第2个之后的任何位置打印。第二个fork之后的打印5和3的顺序也无法确定。因此,可能的输出是:

25235 * 3
25253 * 3
2523个* 35个
2525个* 33个
252个* 335个
252个* 353个
25 * 3235
25 * 3253
2 * 35235
2 * 35253

答案 2 :(得分:1)

由于 fork()的执行顺序不确定,因此您只能期望每个整数(即2,3和5)打印两次。订单取决于调度程序选择如何安排流程。

您可以使用 sleep 命令或其他一些同步原语强制执行特定订单。

答案 3 :(得分:1)

第一个fork()将流程分为两部分(父级和子级)。父母等待,孩子打印2。

然后孩子做fork();孩子打印5并退出(允许父母再次开始跑步),而孩子的孩子(孙子?)打印3.这可以按任何顺序发生。

父母继续并打印2(这可能发生在孙子打印3之前或之后;但在现已终止的孩子打印5之后)。

然后父母做fork();父母打印5,它的第二个孩子打印2(这可以按任何顺序发生,可能发生在孙子打印5之前)。

答案 4 :(得分:0)

第一个fork创建一个子节点并等待它。因此,只要第一个孩子退出,主程序就会继续运行。

所以第一个输出是“孩子的”2。 然后以任意顺序打印35。只有在35第二个2发生后,才会发生,然后是第二个3和/或5

所以

232553 is ok
235325 is not ok, as the 2nd 3 comes before the 2nd 2
232355 is ok
235253 is ok
252533 is ok