等待子进程而不使用wait()

时间:2017-08-30 05:08:03

标签: c multithreading

使用fork()时,是否可以确保子进程在父进程之前执行而不在父进程中使用wait()

这与免费在线操作系统手册Process API chapter Operating Systems: Three Easy Pieces中的作业问题有关。

问题是:

  
      
  1. 使用fork()编写另一个程序。子进程应该   打印“你好”;父进程应打印“再见”。你应该   尽量确保子进程始终先打印;你可以做   这个没有在父母中调用wait()吗?
  2.   

以下是我使用wait()的解决方案:

#include <stdio.h>
#include <stdlib.h> // exit
#include <sys/wait.h> // wait
#include <unistd.h> // fork

int main(void) {
    int f = fork();
    if (f < 0) { // fork failed
        fprintf(stderr, "fork failed\n");
        exit(1);
    } else if (f == 0) { // child
        printf("hello\n");
    } else { // parent
        wait(NULL);
        printf("goodbye\n");
    }
}

在考虑之后,我决定最后一个问题的答案是“不,你不能”,但后来的问题似乎暗示你可以:

  
      
  1. 现在编写一个使用wait()等待子进程的程序   完成父母。 wait()返回什么?如果发生什么   你在孩子身上使用wait()吗?
  2.   

我是否错误地解释了第二个问题?如果没有,你怎么做第一个问题要求?如何在父母不使用wait()的情况下首先打印孩子?

4 个答案:

答案 0 :(得分:1)

我无法理解为什么第二个问题会暗示答案是&#34;是&#34;到第一个。

是的,有很多解决方案可以获得所要求的内容,但当然我怀疑所有这些都不属于&#34;精神&#34;关注fork/wait原语的问题/问题。重点是要记住,在关于流程相对于彼此运行的方式之后,你不能假设任何事情。

为了确保子进程首先打印,您需要在两个进程之间进行一种同步,并且有许多系统原语具有&#34;通信&#34;进程之间(例如锁,信号量,信号等)。我怀疑其中一个是用她的,因为它们通常会在稍后的课程中稍后介绍。

任何其他仅依赖于时间假设的尝试(例如使用sleep或循环来减少&#34;向下父母等)会导致失败,意味着你不会能够证明它将永远成功。即使测试可能会向您显示它似乎是正确的,但您尝试的大多数运行都不会具有导致失败的不良特性。请记住,除了在实时操作系统中,调度几乎是公平并发的近似值。

注:

正如Jonathan Leffler评论的那样,我还假设禁止使用其他wait - 类原语(aka wait4waitpid等) - &#34; spirit&#34;参数。

答案 1 :(得分:1)

我希望这个答案对某些人来说并不晚。

几分钟前,我已经通过电子邮件发送给了Remiz(这本书的作者),并获得了这样的重播(摘录了一段):

  

没有调用wait()很难,而不是真正的主要观点。   你做了什么 - 自己学习信号 - 是一个好兆头,   显示你将寻求更深层次的知识。对你有好处!

     

稍后,您将能够使用共享内存段,并且   无论是条件变量还是信号量,都可以解决这个问题。

他是一位非常负责任的教育家,作家和教授:P

答案 2 :(得分:0)

在父级中创建管道。在fork之后,关闭父级中的写半部分和子级中的读半部分。

然后,poll以提高可读性。由于孩子从不写信,它会等到孩子(以及所有孙子,除非你特别小心)不再存在,此时poll会给出一个&#34;读取与挂断&#34;响应。 (或者,您实际上可以通过管道进行通信)。

您应该阅读O_CLOEXEC。作为一般规则,除非您有充分的理由清除该标志,否则应始终设置该标志。

答案 3 :(得分:0)

我所做的只是在else条件中放置了一个for循环,以便父进程不会立即完成,而子进程将首先打印。但是我想这在技术上并不是在等待子进程,也没有一个糟糕的解决方案来完成任务。 for(i = 1000; i> 0; i ++); 而且,我也不确定使用这种(非道德的)方法,孩子会总是先打印。