我正在编辑这个问题,因为它被标记为重复的另一个关于如何杀死僵尸进程的问题。
我不是在寻找如何杀死僵尸进程的答案。我的系统上没有僵尸,并且我知道僵尸是如何创建的。
让我尝试重新表述这个问题。目前,以下是消除僵尸的公认方法:
向父级发送 SIGCHLD。理论上可行,但在实践中并不总是有效,因为僵尸最初被创建的原因之一可能是因为父进程没有正确响应 SIGCHLD。
杀死父进程。
- 修复了创建僵尸的程序中的错误。
- 重新启动。
或者如所提到的这里
或者出于这个原因,@richard 在编辑之前对我的问题的评论中提到了这一点:
..to prevent the pid being reused. The parent has the pid of the child and may signal the child (may try to kill it), just from the pid it recieved when it created the child. It would be bad for the pid to be reused. Therefore the child remains in a zombie state until the parent acknowledges the death of the child, or the parent dies.
现在我的问题是:
为什么没有直接的方法来清理一个或多个僵尸。
如果僵尸可以用信号杀死,会产生什么副作用/后果?
是什么阻止 *NIX 维护者创建清理僵尸的信号或命令(我很抱歉,如果“创建新信号”这句话在技术上不可接受)。
答案1
该进程当时已经死了。再杀也没意义了。它仍然记录在进程表中,以允许父 ti 获取其状态。
请注意,所有进程被杀死后都会变成僵尸。您只是看不到它们,因为大多数父进程都会很快清理其子进程。如果软件没有清理其僵尸程序并且它们只能通过以下方式清理,您可能需要提交错误报告在里面一旦父进程退出。
您的附加问题是为什么SIGKILL
不将其从进程表中删除。您应该首先告诉我们为什么应该这样做。我不知道有什么理由让用户从进程表中删除已失效的进程。在操作系统设计中,你应该始终有一个做某事的好理由在你问之前为什么不这样做。您要求的功能没有实际用例。
除了缺乏目的之外,它还会带来不好的后果。家长致电wait()
和/或waitpid()
了解退出孩子的状态。无论是在进程变成之前调用,调用的结果都是一致的不复存在的,在发出 之前SIGKILL
,或之后。
如果内核不保留记录(即进程将从进程表中删除),则行为将必须不一致,并且父级将不得不预期不一致并无正当理由地处理它。在重用旧的系统中PID值,不保留记录可能会导致更严重的问题,例如软件意外杀死完全不同的进程。