【问题标题】:How can I check when a Linux process and ALL its children exited?如何检查 Linux 进程及其所有子进程何时退出?
【发布时间】:2017-08-09 14:17:15
【问题描述】:

我用 C 编写了一个程序。我在主进程中执行 fork(),以便在分叉的子进程中执行 execve() 以执行未知应用程序(由用户在命令行中提供)。我知道已执行应用程序的进程的 PID - 它由 fork() 返回,但这个未知的应用程序可能会 fork() 多次,我不知道它所有子进程的 PID(它们是主要父进程的孙子进程)。如何检查主父进程WHEN 其子进程(它是未知应用程序)和未知应用程序退出的ALL 子进程? (我什至不知道它可以有多少个孩子,我也不知道这些孩子的 PID)。

【问题讨论】:

  • 我很确定您无法通过正常方式做到这一点。也许涉及ptrace的事情?
  • 应用程序应该照顾它的孩子。您不必担心它们。
  • @klutt 这不是重复的,因为我的答案无法通过查找不是直接子进程的进程 ID 来解决。
  • @PSkocik 我不担心。我只需要知道它们什么时候都退出。

标签: c linux


【解决方案1】:

这可以通过使您的父进程成为子收割机来完成。一个子收割者让所有被其后代孤立的孩子,传统上总是会进入 init(进程 ID 1)。在派生有趣的子进程之前,需要启用 subreaper 状态。完成此操作后,对任何进程的 waitpid() 或类似调用将返回子进程和所有孤立的后代,直到当整个树消失时返回错误 [ECHILD]

在 Linux 上,这是使用 prctl()PR_SET_CHILD_SUBREAPER 选项启用的,而在 FreeBSD 上,这是使用 procctl() PROC_REAP_ACQUIRE 命令启用的(有关详细信息,请参阅手册页)。

在 Linux 上,您将只能通过这种方式单独监控一个子进程,因为孤儿不记得它们来自哪个原始 fork 调用。在 FreeBSD 上,PROC_REAP_GETPIDS 允许区分各个子树,但如果树包含许多进程,则效率会降低。

【讨论】:

【解决方案2】:

您可以使用 waitpid(-1,NULL, WNOHANG) 来判断一个孩子是否已经退出。如果您收到一个正数(pid),那么一个孩子已经退出。在您的父进程中,您有一行检查您拥有的子进程的数量(此处称为 x)是否大于 0。如果是,请使用此命令查看是否有任何子进程已结束。如果你有 x 个项目,那么当你添加一个项目时,增量 x 并且当一个退出时减量 x。当您拥有的孩子数量 x 为零时,您所有的孩子都被杀死了。

【讨论】:

  • 问题是关于孙子,而不是主进程的子进程。
  • @melpomene 完全正确。
  • @Charles 我想知道我使用 execve() 执行的未知应用程序的所有子项(所以我的孙子)何时退出。我什至不知道这个未知的应用程序可以拥有多少个孩子,我也不知道这些孩子的 PID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-27
  • 1970-01-01
  • 2010-09-21
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多