如何杀死僵尸进程?

226

我启动了一个前台程序(一个守护进程),然后用 kill -9 杀掉它,但是我得到了一个僵尸进程,而且我无法用 kill -9 杀死它。如何杀死一个僵尸进程?

如果这个僵尸进程已经被杀掉了,我该如何将其从 ps aux 的输出中删除?

root@OpenWrt:~# anyprogramd &
root@OpenWrt:~# ps aux | grep anyprogram
 1163 root      2552 S    anyprogramd
 1167 root      2552 S    anyprogramd
 1169 root      2552 S    anyprogramd
 1170 root      2552 S    anyprogramd
10101 root       944 S    grep anyprogram
root@OpenWrt:~# pidof anyprogramd
1170 1169 1167 1163
root@OpenWrt:~# kill -9 1170 1169 1167 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]
root@OpenWrt:~# kill -9 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]

2
ps -o ppid 1163 的输出是什么?也就是说,1163的父进程是谁?那个进程必须被终止。 - William Pursell
9个回答

305
一个僵尸进程已经死亡,因此您无法杀死它。要清除僵尸进程,必须等待其父进程,因此杀死父进程应该可以消除僵尸进程。(在父进程死亡后,僵尸进程将被pid 1继承,它将等待并清除进程表中的条目)。如果您的守护程序生成的子进程变成了僵尸进程,则存在错误。您的守护程序应该注意到其子进程何时死亡,并等待它们以确定其退出状态。
以下是向每个僵尸进程的父进程发送信号的示例(请注意,这非常粗糙,可能会杀死您不想杀死的进程。我不建议使用这种摧毁一切的方法):
# Don't do this.  Incredibly risky sledge hammer!
kill $(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}')

2
如果僵尸进程已经被杀死,我该如何将其从“ps aux”的输出中删除? - MOHAMED
237
这个僵尸必须由它的父母照顾。找到它的父母并弄清楚为什么他们没有关注自己的孩子,然后向社会服务部门投诉。 ;) - William Pursell
1
我认为使用SIGTERM(“kill”命令的默认选项)会更合适,这样可以在退出之前给即将被杀死的进程一个清理的机会。 - jmng
1
假设您有一个产生大量僵尸进程的进程,那么对ID进行“uniq”处理是有意义的:kill $(ps -A -ostat,ppid | awk '/[zZ]/{print $2}' | sort -u) - ankon
4
如果你执行cat /proc/<pid>/status命令,通常可以在PPid行找到父进程的信息。请注意,我将尽力使翻译清晰易懂,但不会更改原意。 - Daniel Andrei Mincă

72

您可以通过使用以下命令杀死其父进程来清除僵尸进程:

kill -HUP $(ps -A -ostat,ppid | awk '{/[zZ]/{ print $2 }')

7
这个命令会清除进程表中的僵尸进程,但不会“杀掉”僵尸进程。僵尸进程已经死亡。 - William Pursell
10
不需要使用 grepps ... | awk '/[zZ]/{print $2}' 的意思是从 ps 命令的输出中找到包含字母“z”或“Z”的行,并打印出它们的第二个字段。 - William Pursell
2
据我所知,这个命令并不能杀死僵尸进程,而是向其父进程发送SIGHUP信号(如果父进程无法处理SIGHUP信号,则可能会导致父进程被杀死,并将僵尸进程重新分配给init进程,正如前面的答案所描述的那样)。因此,在使用此命令时要小心,它可能会意外地杀死您不希望被杀死的进程... - Matthijs Kooijman
1
这对我没用。我执行了“kill -HUP 进程ID”,但进程仍然是僵尸状态。 - kommradHomer
1
@WilliamPursell 当您回答问题时,请详细描述使用命令行的后果以及它明确执行的操作,因为它会杀死计算机上运行的所有程序。 - Dalek
显示剩余6条评论

49

我尝试过:

ps aux | grep -w Z   # returns the zombies pid
ps o ppid {returned pid from previous command}   # returns the parent
kill -1 {the parent id from previous command}

这将有效 :)


在我的情况下,僵尸进程是通过启动脚本和未清除干净的程序创建的,所以我将其清除了。 - Mohammad Rafiee
1
对我有用。在某些情况下,当死亡进程是由另一个被杀进程生成时,这将起作用。 - Eric S. Bullington
2
在终止进程之前,我检查了其父进程。然后我使用-9而不是-1来杀死它:kill -9 {父进程的ID}。 - Ali
我也不得不使用-9来终止我的程序,而不是-1。 - Michael Smith
我必须通过重新启动我的Mac来终止它,因为ppid是1,无法使用sudo命令终止它。 - towry

34

http://www.linuxquestions.org/questions/suse-novell-60/howto-kill-defunct-processes-574612/里找到了它

2) 这里有另一个用户的好提示(感谢Bill Dandreta):有时候

kill -9 <pid>

不会终止一个进程。运行

ps -xal

第四个字段是父进程,杀死所有僵尸进程的父进程,僵尸进程就会消失!

示例

4 0 18581 31706 17 0 2664 1236 wait S ? 0:00 sh -c /usr/bin/gcc -fomit-frame-pointer -O -mfpmat
4 0 18582 18581 17 0 2064 828 wait S ? 0:00 /usr/i686-pc-linux-gnu/gcc-bin/3.3.6/gcc -fomit-fr
4 0 18583 18582 21 0 6684 3100 - R ? 0:00 /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/cc1 -quie

185811858218583是僵尸 -

kill -9 18581 18582 18583

没有影响。

kill -9 31706

清除僵尸。


5
那刚刚让我失去了init,现在我什么也做不了,只能强制重启... 僵尸进程是Java,占用4GB RAM中的3.4GB。 - Tcll

29

我尝试过

kill -9 $(ps -A -ostat,ppid | grep -e '[zZ]'| awk '{ print $2 }')

而且这对我很有效。


1

将几个答案结合起来,提供一种优雅的方法,在杀死僵尸进程之前确认哪个进程已经变成僵尸。将脚本添加到.bashrc/.zshrc中并运行killZombie命令。

killZombie() {
    pid=$(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}');
    if [ "$pid" = "" ]; then
        echo "No zombie processes found.";
    else
        cmd=$(ps -p $pid -o cmd | sed '1d');
        echo "Found zombie process PID: $pid";
        echo "$cmd";
        echo "Kill it? Return to continue… (ctrl+c to cancel)";
        read -r;
        sudo kill -9 $pid;
    fi
}

1
有时候无法杀死父进程的ppid,因此需要杀死僵尸进程的pid。
kill -9 $(ps -A -ostat,pid | awk '/[zZ]/{ print $2 }')

0

在 Mac 上,上述命令/指令均无效。要删除僵尸进程,您可以右键单击 Docker 图标 -> 故障排除 -> 清理/清除数据。

enter image description here


0

我不敢尝试上述方法。

我的解决方案是使用htop检测具有multiprocessing.spawn的进程并使用kill -9命令终止它。


如果你敢看别人的答案,你会发现被接受的答案解释并给出了要运行的确切 kill 命令(只需一步)。 - Elikill58

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接