从进程表中删除一个僵尸进程

我有一个令人讨厌的僵尸进程,被init采纳,它不会消失。 我读过有一种方法可以创build一个虚拟的进程,将僵尸作为新进程的一个subprocess, 然后杀死它,从进程表中删除它。

我该怎么做呢?

是的,我已经阅读了大部分的东西:

僵尸进程已经死了,所以不能被杀死。

要么

你应该重新启动你的系统

僵尸进程不使用任何资源,你应该让他们成为

不幸的是,很多程序检查进程表,看是否有一个实例正在运行,如果进程表中有条目,将拒绝启动一个新进程。

每当我的SSHFS连接断开时,重新启动,带着崇高的,是愚蠢的。

摆脱僵尸的唯一方法是使其父母wait()以便它可以报告其退出状态。 你可以通过发送SIGCHLD到父级,假设父级写入正确。

如果你有僵尸,通常意味着父母不能正确书写(因为孩子已经在其死亡并成为僵尸的时候向其父母发送了SIGCHLD ),所以下一步就是杀死父母。
pstree这样的工具(带有-p选项)可以显示你的僵尸血统,所以你知道哪个进程是父进程。
当父母死亡的时候,僵尸会被init所采纳,而这个init会一直wait()孩子死亡,并且会高兴地杀死所有的僵尸。

如果父进程实际上是init (PID 1),那么你就处于一种永远不会发生的状态。 你可以尝试发送SIGCHLDinit ,但你真的不应该这样做,如果这不起作用,唯一的办法就是重新启动,因为你的系统的init已经坏了,没有完成它的工作。

(这些是“霰弹枪”选项。)


一些比我更有创意的人也提出了这个选项,如果你想避免杀死父进程:

  1. 确定僵尸和父母进程的PIDS
    (在这个例子中,假设僵尸是PID 3101,父亲是PID 3100)
  2. 启动gdb attach加到父级:
    attach 3100
  3. 为僵尸呼叫waitpid
    call waitpid(3101,0,0)
  4. 从父( detachdetach并退出debugging器。

(这是一个精心调整的狙击步枪。)

你为什么担心僵尸进程? 他们保持捆绑的资源是最小的(一个框架结构任务的空间,一个PID,而不是其他)。 当然,这是不合时宜的,但就是这样。 search他们的父母,并修复这些,取而代之的是更好的书面select(可能有其他有益的副作用),报告为错误(他们当然是)。