我有一个恼人的僵尸进程,被init采用,它不会消失.
我已经读过有一种方法可以创建一个虚拟进程,将僵尸作为该新进程的子进程附加,然后将其删除,将其从进程表中删除.
我已经读过有一种方法可以创建一个虚拟进程,将僵尸作为该新进程的子进程附加,然后将其删除,将其从进程表中删除.
我该怎么做呢?
是的,我已经阅读了大部分内容:
一个僵尸进程已经死了,所以它不能被杀死.
要么
你应该重新启动你的系统
和
僵尸进程不使用任何资源,你应该让它们成为现实
不幸的是,许多程序检查进程表以查看实例是否已在运行,并且如果进程表中有条目,则拒绝启动新实例.
每次我的SSHFS连接退出时重新启动,使用Sublime,有点愚蠢.
解决方法
摆脱僵尸的唯一方法是使其父等待(),以便它可以报告其退出状态.您可以通过向父节点发送SIGCHLD来做到这一点,假设父节点写得正确.
如果你有僵尸,通常意味着父母没有被正确写入(因为孩子已经将SIGCHLD发送给它的父母,当它死了并变成了僵尸),所以下一步是杀死父母.
像pstree这样的工具(使用-p选项)可以显示僵尸的血统,因此您知道哪个进程是父进程.
当父母去世时,僵尸将被init采用,这总是等待儿童死亡,并且会愉快地杀死它所采用的所有僵尸.
如果父进程实际上是init(PID 1),那么你处于一种永远不会发生的情况.您可以尝试将SIGCHLD发送到init,但是您真的不应该这样做,如果这不起作用,您唯一的办法就是重新启动,因为系统的init已损坏且无法正常工作.
(这些是“霰弹枪”选项.)
如果你想避免杀死父进程,一些more creative folks than I也提出了这个选项:
>确定僵尸&父流程’PIDS
(对于这个例子,假设僵尸是PID 3101,父亲是PID 3100)
>启动gdb并附加到父级:
附上3100
>为僵尸调用waitpid:
call waitpid(3101,0)
>从父级分离(分离)并退出调试器.
(这是一个精心调整的狙击步枪.)