我尝试根据代码绘制过程,但我真的需要解释原因,这里是问题:
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)
所以我被困在那里......感谢任何帮助。
答案 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
。
然后以任意顺序打印3
和5
。只有在3
或5
第二个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