【问题标题】:Will wait() calls be executed in a predictable order?wait() 调用会以可预测的顺序执行吗?
【发布时间】: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”消息出现之前。

标签: c fork posix wait


【解决方案1】:

进程 0 将始终等待进程 1,因为这是它拥有的唯一子进程。 并且进程 1 将始终等待进程 2,因为这是它拥有的唯一子进程。

在进程 1 退出之前,进程 0 不会从 wait 返回,这意味着进程 1 已经打印了它的消息,因为它是在退出之前完成的。

所以在这种情况下,进程 0 直到消息被打印后才能继续。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    相关资源
    最近更新 更多