【发布时间】:2016-03-15 02:48:27
【问题描述】:
我在流式传输实时数据方面做了很多工作,我发现用于将我的系统的不同部分相互隔离的流程模型非常有效。在程序的生命周期中,能够以流方式打开子进程并从中读取数据通常非常方便/简洁。但是,如果子进程在父进程结束之前没有正确地等待(),那么您很容易以僵尸或孤儿结束。
我正在寻找的基本上是在正确清理子进程时获得 RAII 风格的保证。理想情况下,不管如何父退出,无论是响应信号、调用exit()、抛出异常等等。知道我永远无法生成僵尸或孤立进程,我想安然入睡。
【问题讨论】:
-
你不能,因为
kill -9,但一般来说你需要确保所有的孩子都是wait()-ed。这在所有出口路径上都是不可行的,例如信号处理程序。 -
如果父进程已经退出,那么僵尸进程有什么问题?他们将被
init收养并等待。另一方面,孤儿是另一回事。所以要澄清一下,你真的关心父母死后的僵尸吗?如果是,为什么? -
好吧,我坚信要清理干净自己,所以如果我能避开僵尸就更好了,但我绝对不能留下任何孤儿。
-
不知道这是否适用于您的情况,但我让我的孩子在标准输入上处理 select() (以及其他描述符),因此当他们的标准输入句柄关闭时,他们会注意到它,并通过尽快退出。这样,如果/当父进程消失(出于任何原因),子进程也会消失。
-
你可以安排向一个进程组中的所有进程发送信号,所以如果你的父进程形成了自己的进程组,子进程将在其中,父进程可以发送
SIGTERM,例如,在离开之前给孩子们。你仍然容易受到单方面杀死父母的影响——例如。通过SIGKILL信号。当你的孩子写到一个不再有阅读器的管道时,他们应该死掉——假设你已经在孩子身上正确地完成了你的管道。如果你最终得到孤儿,很可能是你没有关闭足够多的管道,所以系统不知道孩子应该死。