【问题标题】:Wait until all background jobs have terminated, C等到所有后台作业都终止,C
【发布时间】:2016-05-29 16:36:14
【问题描述】:

我知道 waitpid(-1...) 如何让我等到所有孩子都完成后,例如 waitpid(-1, &status)。但是我怎样才能等到所有 后台 进程完成?有人建议我可以使用相同的 waitpid(在循环中?)来实现这一点,但我不知道如何。

需要说明的是,我正在实现一个shell,并且需要添加一个新的内置命令wait,它会等到所有后台作业都终止后再返回提示。

我在 SO 上的其他地方读到“您还需要定期调用带有 WNOHANG 选项的 waitpid() - 例如,在您显示 shell 提示符之前。这将允许您检测后台进程何时退出或停止“但是,孩子!=背景。所以即使这样我也不相信。


编辑:

我最终只是在做 while(wait(NULL) > 0);就是这样,它奏效了。但是我仍然感到困惑的是,我不想区分前台和后台,因为我正在实现的等待只等待后台进程,并且在 wait() 或 waitpid 的眼中所有孩子都是平等的()。

同样,我使用 wait() 或 waitpid() 等待的子进程不一定是后台进程。我错了吗?

【问题讨论】:

  • C 没有“后台进程”的概念。背景与前景是外壳作业控制的事情。那么是什么意思呢?
  • 我正在实现一个shell,所以你完全正确。

标签: process fork wait pid


【解决方案1】:

由于您在实现 shell 的上下文中询问,并且显然您的 shell 支持足够的作业控制以具有后台进程的概念,因此可以合理地假设您的实现将有一个用于跟踪后台作业的表。该表可以并且应该跟踪与每个作业关联的进程的 PID。

有了这些 PID,您可以 waitpid() 获取特定的后台作业,直到表格中没有更多内容为止,或者您可以 waitpid(-1) 收集 循环中的所有作业,直到表中没有更多的后台作业。

【讨论】:

  • 你能详细说明一下 waitpid(-1) 循环吗?我假设您的意思是带有 WNOHANG 选项的 waitpid(-1)。
  • @ajfbiw.s,这取决于你想要的语义。您的问题要求等待,直到所有后台作业完成,这表明阻塞——即使用WNOHANG。事实上,如果每条跳出循环的路径都要求您收集至少一个孩子,那么使用 WNOHANG 毫无意义。
  • 我最终只是在做 while(wait(NULL) > 0);就是这样,它奏效了。但是我仍然感到困惑的是,我不想区分前台和后台,因为我正在实现的等待只等待后台进程,并且在 wait() 或 waitpid 的眼中所有孩子都是平等的()。
  • 再说一次,我使用 wait() 或 waitpid() 等待的子进程不一定是后台进程。我错了吗?
  • @ajfbiw.s,正如我之前写的,前景与背景是 shell 强加的区别。 wait()waitpid() 对此毫无概念。但是请注意,当 shell 本身在前台时,所有它的托管作业都必须在后台。如果您只需要在这种情况下执行此任务,那么等待所有子进程可能就可以了。
【解决方案2】:

如果您想实现后台进程(和作业控制)并捕获它们的终止(至少),您必须为SIGCHLD 设置一个信号处理程序,并在其中调用wait(-1)。这将使您的 shell 接收后台进程终止的异步通知。例如,您可以查看Catching SIGCHLD 并对此进行讨论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2016-05-16
    • 2014-01-31
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2012-10-17
    相关资源
    最近更新 更多