僵尸进程也称为“已失效”或“死亡”进程 - 简而言之,僵尸进程是已死亡但存在于系统进程表中的进程。理想情况下,一旦完成其作业/执行,它就应该从进程表中清除,但由于某种原因,其父进程在执行后没有正确清除它。
在 Linux 世界中,进程一旦完成执行并退出,就会通知其父进程。然后父进程将从进程表中删除该进程。在此步骤中,如果父进程无法从其子进程(已完成的进程)读取进程状态,则它将无法从内存中删除该进程,因此死亡的进程仍然继续存在于进程表中——因此,被称为僵尸!
僵尸进程因为没有清理干净,因此仍然会占用端口等资源,这样会影响其他需要使用该资源的进程。
为了杀死僵尸进程,我们需要首先识别它。以下命令可用于查找僵尸进程:
$ ps aux | egrep "Z|defunct"#或者使用如下方式更加简洁ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'
输出的STAT 列中的Z和/或最后 (COMMAND) 列中的[defunct]将标记为僵尸进程。
现在我们实际上无法杀死僵尸,因为它已经死了!可以做的是显式通知其父进程,以便它可以重试读取子进程的状态并最终将其从进程表中清除。这可以通过向父进程发送SIGCHLD信号来完成。可以使用以下命令查找父进程 ID (PID):
$ ps -o ppid= <Child PID>
一旦获得了 Zombie 的父进程 ID,就可以使用以下命令向父进程发送SIGCHLD信号:
$ kill -s SIGCHLD <Parent PID>
但是,如果这无助于清除僵尸进程,我们将不得不终止或重新启动其父进程,或者如果僵尸进程大幅增加导致或导致系统中断,我们将别无选择,只能寻求系统重新启动。以下命令可用于终止其父进程:
$ kill -9 <Parent PID>
请注意,终止父进程将影响其所有子进程,因此快速双重检查将有助于确保安全。或者,如果少数僵尸进程没有消耗太多 CPU/内存,最好在下一次计划的系统维护中杀死父进程或重新启动系统。