找到并杀掉 Linux 系统中的僵尸进程

大部分 Linux 系统进程最大 PID 设置为 32768,如果过多僵尸进程导致其他重要任务没有 PID 可用,系统会发生崩溃。需要找到并杀死僵尸进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-134-generic x86_64)

System information as of Fri Mar 21 10:38:43 AM CST 2025

System load: 0.02
Usage of /: 44.3% of 79.95GB
Memory usage: 17%
Swap usage: 1%
Processes: 180
Users logged in: 0
IPv4 address for ens133: 192.168.0.5
IPv6 address for ens133: 2409:8a04:2567:c580:2e0:4cff:fe36:127c

=> There is 1 zombie process.

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

Last login: Fri Mar 21 08:07:59 2025 from 192.168.0.14

ssh登录主机,发现提示:”=> There is 1 zombie process.”

进程

进程是一个程序的运行实例。它可能运行在前端(比如有交互的进程),也可能运行在后端(比如无交互或自动运行的进程)。它可能是一个父进程(运行期间创建了其他进程),也可能是一个子进程(由其他进程所创建)。
在 Linux 系统中,除 PID 为 0 的第一个 init 进程(或 systemd)外,其余进程都有父进程。进程也可以拥有自己的子进程。
在终端中使用 pstree 命令查看进程的树型结构,能看到系统各个进程的“家族树”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
qs@ubuntu:~$pstree
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager───2*[{NetworkManager}]
├─agetty
├─containerd───11*[{containerd}]
├─containerd-shim─┬─s6-svscan─┬─s6-supervise───s6-linux-init-s
│ │ ├─s6-supervise───s6-ipcserverd
│ │ ├─s6-supervise───qbittorrent-nox───8*[{qbittorrent-nox}]
│ │ ├─s6-supervise───busybox
│ │ └─s6-supervise
│ └─11*[{containerd-shim}]
├─containerd-shim─┬─agent───5*[{agent}]
│ └─11*[{containerd-shim}]
├─containerd-shim─┬─node───10*[{node}]
│ └─11*[{containerd-shim}]
├─containerd-shim─┬─xlp─┬─xlp─┬─xlp─┬─xunlei-pan-cli-─┬─xunlei-pan-cli.───22*[{xunlei-pan-cli.}]
│ │ │ │ │ └─9*[{xunlei-pan-cli-}]
│ │ │ │ └─10*[{xlp}]
│ │ │ └─7*[{xlp}]
│ │ └─7*[{xlp}]
│ └─11*[{containerd-shim}]
├─containerd-shim─┬─filebrowser───7*[{filebrowser}]
│ └─11*[{containerd-shim}]
├─cron
├─dbus-daemon
├─dockerd─┬─6*[docker-proxy───7*[{docker-proxy}]]
│ ├─docker-proxy───8*[{docker-proxy}]
│ ├─docker-proxy───6*[{docker-proxy}]
│ └─20*[{dockerd}]
├─irqbalance───{irqbalance}
├─jellyfin───16*[{jellyfin}]
├─multipathd───6*[{multipathd}]
├─networkd-dispat
├─nmbd
├─polkitd───2*[{polkitd}]
├─rsyslogd───3*[{rsyslogd}]
├─smbd─┬─cleanupd
│ ├─samba-bgqd
│ └─smbd-notifyd
├─sshd───sshd───sshd───bash───pstree
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-network
├─systemd-resolve
├─systemd-udevd
├─unattended-upgr───{unattended-upgr}
├─v2ray───8*[{v2ray}]
├─v2raya───8*[{v2raya}]
└─wpa_supplicant

僵尸进程

子进程死亡后,它的父进程会接收到通知去执行一些清理操作,如释放内存之类。然而,若父进程并未察觉到子进程死亡,子进程就会进入到“ 僵尸(zombie)”状态。从父进程角度看,子进程仍然存在,即使子进程实际上已经死亡。这就是“ 僵尸进程(zombie process)”(也被称为“ 已消失进程(defunct process)”)是如何产生并存在于系统中的。
进程可能处于如下状态中的一种:
D = 不可中断的休眠
I = 空闲
R = 运行中
S = 休眠
T = 被调度信号终止
t = 被调试器终止
Z = 僵尸状态
如何查看进程和它的当前状态呢?一个简单的方法是在终端中使用 top 命令。

1
2
3
4
5
6
7
qs@ubuntu:~$top
top - 15:46:57 up 4:27, 1 user, load average: 0.02, 0.02, 0.00
Tasks: 176 total, 1 running, 175 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3774.1 total, 548.7 free, 610.6 used, 2614.7 buff/cache
MiB Swap: 3767.0 total, 3695.7 free, 71.2 used. 2829.9 avail Mem
...

处理僵尸进程

确定僵尸进程的相关信息,比如父进程ppid、僵尸进程的pid以及命令行等信息。可以执行如下命令:
ps -e -o stat,ppid,pid,cmd | egrep '^[Zz]'
说明:
ps:ps命令用于获取当前系统的进程信息
-e:参数用于列出所有的进程
-o:参数用于设定输出格式,这里只输出进程的stat(状态信息)、ppid(父进程pid)、pid(当前进程的pid),cmd(即进程的可执行文件
egrep:是linux下的正则表达式工具:‘1’:这是正则表达式,表示第一个字符的位置,[Zz],表示z或者大写的Z字母,即表示第一个字符为Z或者z开头的进程数据,只所以这样是因为僵尸进程的状态信息以Z或者z字母开头。
然后可以kill -9 父进程pid,假设父进程pid为 1024
kill -9 1024