【问题标题】:What does it take to _guarantee_ that child processes are killed before parent exits in linux?如何保证子进程在 linux 中父进程退出之前被杀死?
【发布时间】:2016-03-15 02:48:27
【问题描述】:

我在流式传输实时数据方面做了很多工作,我发现用于将我的系统的不同部分相互隔离的流程模型非常有效。在程序的生命周期中,能够以流方式打开子进程并从中读取数据通常非常方便/简洁。但是,如果子进程在父进程结束之前没有正确地等待(),那么您很容易以僵尸或孤儿结束。

我正在寻找的基本上是在正确清理子进程时获得 RAII 风格的保证。理想情况下,不管如何父退出,无论是响应信号、调用exit()、抛出异常等等。知道我永远无法生成僵尸或孤立进程,我想安然入睡。

【问题讨论】:

  • 你不能,因为kill -9,但一般来说你需要确保所有的孩子都是wait()-ed。这在所有出口路径上都是不可行的,例如信号处理程序。
  • 如果父进程已经退出,那么僵尸进程有什么问题?他们将被init收养并等待。另一方面,孤儿是另一回事。所以要澄清一下,你真的关心父母死后的僵尸吗?如果是,为什么?
  • 好吧,我坚信要清理干净自己,所以如果我能避开僵尸就更好了,但我绝对不能留下任何孤儿。
  • 不知道这是否适用于您的情况,但我让我的孩子在标准输入上处理 select() (以及其他描述符),因此当他们的标准输入句柄关闭时,他们会注意到它,并通过尽快退出。这样,如果/当父进程消失(出于任何原因),子进程也会消失。
  • 你可以安排向一个进程组中的所有进程发送信号,所以如果你的父进程形成了自己的进程组,子进程将在其中,父进程可以发送SIGTERM,例如,在离开之前给孩子们。你仍然容易受到单方面杀死父母的影响——例如。通过SIGKILL 信号。当你的孩子写到一个不再有阅读器的管道时,他们应该死掉——假设你已经在孩子身上正确地完成了你的管道。如果你最终得到孤儿,很可能是你没有关闭足够多的管道,所以系统不知道孩子应该死。

标签: c++ c linux


【解决方案1】:

在您的代码中,当您知道孩子pid 时,可能作为对fork() 的调用的返回值,代码可以通过以下方式等待孩子死亡:

waitpid( pid, &status, 0);

如果父进程实际上对该状态感兴趣,则可以随后进行适当的宏调用以从子进程中提取返回的状态。

注意:不等待子进程死亡可能会导致创建zombie 进程。这通常需要重新启动才能消除

【讨论】:

  • 当然可以,但这不适用于任何类型的父级异常终止。
猜你喜欢
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多