忽略子进程退出状态的Fork操作

2 投票
2 回答
2414 浏览
提问于 2025-04-18 12:31

我正在写一个后台程序,它可以自动更新多个长时间运行的程序。我不关心这些程序的退出状态,因为它们只有在升级时被强制退出时才会结束。不过,这样做的结果是我产生了很多“僵尸进程”。

我知道可以使用 waitpid(0, WNOHANG) 来监听任何子进程的状态变化(这几乎正是我想要的),但是我还在使用 Python 的多进程模块来同时运行多个独立的升级进程。因此,能够运行 waitpid 的长时间运行的进程实际上是被终止进程的“祖父进程”,所以它根本收不到任何信号。

那么,有没有办法让子进程在运行时不需要检查退出状态,或者我就只能忍受我的进程表被僵尸进程填满呢?

2 个回答

0

根据我对你进程树布局的理解,它看起来像下面这样,其中 parent1parent2 是使用 Python 的 multiprocessing.Process 对象的部分。

grandparent
 |- parent1
   |- child1
   |- child2
 |- parent2
   | - child1
   | - child2

如果是这样的话,你需要确保在父进程(也就是 parent1parent2)中调用 multiprocessing.Process.join,这样才能处理它们各自的子进程。一旦子进程结束,无论是什么原因,它们都会被清理,这样 grandparent 就可以顺利地清理 parent1parent2

如果你想在父进程中添加一些额外的逻辑,以便遍历所有子进程,而不是只等待第一个子进程结束,你可以使用 timeout 这个参数,具体可以参考 这个链接,来设置等待的时间限制。

7

你可以通过设置SIGCHLD的信号处理器来控制这个。

在C语言中,你会这样做:

signal(SIGCHLD, SIG_IGN);

你需要把这个调整成Python的接口。

你可以使用Python 2的signal模块或者Python 3的signal模块;它们在这个问题上看起来是一样的:

import signal

signal.signal(signal.SIGCHLD, signal.SIG_IGN)

可以参考POSIX的信号概念,了解底层系统的行为(特别是“信号动作”和该部分下的SIG_IGN)。

警告:Python代码未经过正式测试!

撰写回答