Linux 系统中,进程就是一个程序的运行实例。它可能运行在前端(比如有交互的进程),也可能运行在后端(比如无交互或自动运行的进程)。它可能是一个父进程(运行期间创建了其他进程),也可能是一个子进程(由其他进程所创建)。
在 Linux 系统中,除 PID 为 0 的第一个 init
进程(或 systemd
)外,其余进程都有父进程。进程也可以拥有自己的子进程。
你可以通过使用 pstree 命令来查看进程的树型结构,你可以清晰的看到各个进程的“家族树”。
什么是僵尸进程
在 Linux 系统中,正常情况下,子进程死亡后其父进程会接收到通知进行一些例如释放内存之类的清理操作。但是,如果父进程未收到通知察觉子进程死亡,那么子进程就进入了“僵死”状态。
这就是僵死进程产生的原因。
碰到僵尸进程怎么办?
僵尸进程并不可怕,少量的僵尸进程对系统影响并不大。但如果系统的内存已经所剩不多或者有太多的僵尸进程在耗掉内存,问题会变得糟糕。
同样,大部分 Linux 系统进程最大 PID 设置为 32768,如果过多僵尸进程导致其他重要任务没有 PID 可用,那么你的系统会发生崩溃。
特别当存在一个编码糟糕的程序开始大量产生僵尸进程的时候,这种情况经常发生。在这种情况下,我们就需要找到并杀死僵尸进程。
如何查找僵尸进程
在linux系统中,进程有如下几种状态,它们随时可能处于以上状态中的一种:
D
= 不可中断的休眠I
= 空闲R
= 运行中S
= 休眠T
= 被调度信号终止t
= 被调试器终止Z
= 僵尸状态
我们可以在命令终端中通过top命令来查看系统进程和它的当前状态。
命令如下:
top
如上面截图中看到的,其中共有 250 个任务(进程),其中 1 个处在 “运行中running” 状态,248 个进程处于 “休眠sleep” 状态,还有一个处于 “僵尸zombie” 状态。
现在问题进入下一步,如何杀死 “僵尸” 进程?
杀死僵尸进程
僵尸进程对系统来说就是已经死亡的进程,那么如何杀掉一个已经死亡的进程呢?
方法很简单,我们只需要通过如下ps命令就可以列举僵尸进程,得到它们的进程 ID。
ps ux | awk '{if($8=="Z+") print}'
ps ux
命令输出的第 8 列显示了进程状态。上述命令将会打印所有处在 Z+ 状态(表示僵尸状态)的进程。
确认了进程 ID 后,我们可以得到它的父进程 ID:
ps -o ppid= -p <child_id>
你也可以将上述两个命令结合在一起,直接得到僵尸进程的 PID 及其父进程的 PID:
ps -A -ostat,pid,ppid | grep -e '[zZ]'
通过以上命令都可以找到僵尸进程,然后你就可以通过kill命令杀掉了。
kill -9 父进程号
或者通过如下命令查看僵尸进程:
ps -ef | grep defunct
该命令输出结果上你可以直接看出其父进程ID,这时候你直接使用kill命令杀掉即可。
再次运行 ps
命令或 top
命令,你可以验证僵尸进程是否已经被杀死。