简体   繁体   English

叉子的概念,不太了解叉子的工作原理

[英]Fork concept, dont quite grasp how fork works

I try to draw out the process according to the code but I really need some explanation in why, here is the question: 我尝试根据代码绘制流程,但是我确实需要一些解释,为什么会出现以下问题:

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...

This is the process I draw out according to the code and my understanding of fork. 这是我根据代码和对fork的理解得出的过程。

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

So I'm stuck right there... Any help is appreciated. 所以我被困在那里...任何帮助,我们感激不尽。

Okay, there are two forks. 好的,有两个叉子。 Here is control flow, from left to right, with parents on top and children on the bottom: 这是从左到右的控制流,父母在顶部,孩子在底部:

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

So, what do we know? 那么,我们知道什么?

  • "2", "5", and "3" each appear twice (90 possibilities) “ 2”,“ 5”和“ 3”分别出现两次(90种可能性)

  • No prefix may contain more "3" than "2" (30 possibilities) 前缀不能包含比“ 2”更多的“ 3”(30种可能性)

  • No prefix may contain more "5" than "2" (16 possibilities) 前缀不能包含比“ 2”更多的“ 5”(16种可能性)

  • The second "2" must be preceded by the first "5" (7 possibilities) 第二个“ 2”之前必须是第一个“ 5”(7种可能性)

The 7 possibilities are: 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

This should be the program path ( x denotes termination): 这应该是程序路径( x表示终止):

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

After the first fork , the parent waits for the child to finish. 在第一次fork ,父母等待孩子完成。 But in case of second fork , it does not wait. 但是在第二次fork情况下,它不会等待。 So, * marked 3 can be printed anywhere after first 2. The order of printing 5 and 3 after second fork also can not be determined. 因此,标记为3的*可以在第一个2之后的任何位置打印。第二个fork之后的打印5和3的顺序也无法确定。 Therefore, the possible outputs are: 因此,可能的输出为:

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

Since the order of execution with fork() is not deterministic, you can only expect that each integer (ie, 2, 3 and 5) will be printed twice. 由于fork()的执行顺序不确定,因此只能期望每个整数(即2、3和5)将打印两次。 The order depends on how the scheduler chooses to schedule the processes. 顺序取决于调度程序如何选择调度进程。

You can force a particular order using sleep commands or some other synchronization primitive. 您可以使用睡眠命令或某些其他同步原语强制执行特定顺序。

The first fork() splits the process into 2 parts (parent and child). 第一个fork()将过程分为两部分(父项和子项)。 The parent waits and the child prints 2. 父母等待,孩子打印2。

Then the child does fork() ; 然后孩子做fork() ; and then child prints 5 and exits (which allows the parent to start running again) while the child's child (grandchild?) prints 3. This can happen in any order. 然后,孩子打印5并退出(允许父级再次开始运行),而孩子的孩子(孙子?)打印3。这可以以任何顺序进行。

The parent continues and prints 2 (this may happen before or after the grandchild prints 3; but after the now terminated child printed 5). 父母继续打印2(这可能发生在孙子打印3之前或之后;但在现在终止的孩子打印5之后)。

Then the parent does fork() ; 然后父母做fork() ; and the parent prints 5 and it's second child prints 2 (which can happen in any order, and may happen before the grandchild prints 5). 父级打印5,第二个子级打印2(这可以以任何顺序发生,并且可能在孙子打印5之前发生)。

The first fork creates a child and waits for it. 第一个叉子创建一个孩子并等待它。 So the main program only goes on running as soon as the first child exits. 因此,主程序只有在第一个孩子退出后才继续运行。

So the first output is "the child's" 2 . 因此,第一个输出是“孩子的” 2 Then a 3 and a 5 is printed, in any order. 然后以任意顺序打印35 Only after the 3 or the 5 the second 2 can occur, and then the second 3 and/or 5 . 仅在35之后,才能出现第二个2 ,然后是第二个3和/或5

So 所以

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM