【发布时间】:2019-07-07 21:27:51
【问题描述】:
假设我有以下代码:
pid_t pid0, pid1;
pid0 = fork();
if (!pid0) {
pid1 = fork();
if (!pid1) { // p2
/* do something */
return;
} else { // p1
wait(NULL);
printf("p1 done\n");
return;
}
}
// p0
wait(NULL):
printf("p0 done\n");
打印语句的顺序是确定性的,还是取决于 CPU 的意愿?在实践中,似乎每次都是一样的,但wait() 的文档使它看起来应该是随机的。
编辑:我已经考虑了更多,我想知道它是否总是按这个顺序排列,因为 p0 没有 p2 作为子进程;那是p1的孩子。所以“p0 done”在 p1 完成等待它的孩子 p2 之前不会打印。所以,我想真正的问题是wait() 是在等待孩子的孩子,还是只处理一个“世代”
【问题讨论】:
-
你只能说它不能保证。
-
如果你想要一个有保证的执行顺序,就使用显式同步 => 如果你不使用同步,那么你就得不到一个有保证的顺序。根据一个非保证的序列,偶尔以不同的方式发生可能会导致非常偶然的莫名其妙/不可重现的错误。
-
wait只等待进程的直接子代,而不是孙代。 -
wait()文档的哪个方面让您认为它是不确定的?您已经对其进行了编码,因此它是确定的,AFAICS。在 p2 退出之前,“p1 done”消息不会出现。消息必须在 p1 终止之前刷新,几乎不管 p1 返回后会发生什么。一个可能的例外是,如果输出既不是行缓冲也不是非缓冲的,并且返回后的 p1 代码执行_exit()或quick_exit()— 那么 p1 消息将不会出现)。否则,p0 正在等待 p1; p1 的输出必须出现在“p0 done”消息出现之前。