前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >清理linux中的僵尸进程

清理linux中的僵尸进程

作者头像
入门笔记
发布2022-06-02 16:35:28
3.4K0
发布2022-06-02 16:35:28
举报
文章被收录于专栏:入门小站

什么是僵尸进程

Linux 中的僵尸进程有时也称为失效或死进程。它们是已完成执行的进程,但它们的条目并未从进程表中删除。

进程状态

Linux 维护着所有正在运行的进程及其状态的进程表。让我们简要概述各种进程状态:

  • 正在运行 (R):这些进程当前正在运行或可运行。
  • 等待 (S/D):这些是等待事件或资源的进程。等待可以是可中断睡眠 (S) 或不可中断睡眠 (D)。
  • 停止(T):我们可以通过发送适当的信号来停止Linux 进程。
  • 僵尸(Z):当一个进程完成它的任务时,它会释放它正在使用的系统资源并清理它的内存。但是,它从进程表中的条目不会被删除,它的状态被设置为EXIT_ZOMBIE

僵尸进程的创建

当一个进程完成它的工作时,Linux 内核通过发送SIGCHLD 信号通知退出进程的父进程。然后父进程执行wait()系统调用来读取子进程的状态并获取退出代码。这也会从进程表中清除子进程的条目,此进程结束。

如果父进程没有被编程为在创建子进程时执行wait()系统调用,则不会发生清理。在这种情况下,父进程无法监视子进程的状态变化,最终会忽略SIGCHLD信号。这会导致已完成进程的僵尸状态留在进程表中,因此它作为僵尸进程出现在进程列表中。

另一种情况是父进程无法处理或接收来自子进程的SIGCHLD信号。这种情况也会导致僵尸的产生。

僵尸进程的识别

我们可以使用ps命令识别僵尸列表:

代码语言:javascript
复制
$ ps ux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 191040  2828 ?        Ss   Aug18  14:39 /usr/lib/systemd/systemd --system --deserialize 20
root         2  0.0  0.0      0     0 ?        S    Aug18   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        S<   Aug18   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        S    Aug18   0:23 [ksoftirqd/0]
root         7  0.0  0.0      0     0 ?        Z    Aug18   0:09 [migration/0]
root         8  0.0  0.0      0     0 ?        S    Aug18   0:00 [rcu_bh]

ZSTAT

使用awk命令进一步过滤基于Z进程状态的输出:

代码语言:javascript
复制
$ ps ux | awk '{if($8=="Z") print}'
shubh       108  0  0      0     0 tty1     Z    16:25   0:00 [zombie] <defunct>

检查僵尸进程的数量和列表的另一种方便的方法是使用top 命令:

代码语言:javascript
复制
$ top
Tasks:   8 total,   1 running,   6 sleeping,   0 stopped,   1 zombie
%Cpu(s):  7 us,  6 sy,  0 ni, 5 id,  0 wa,  2 hi,  0 si,  0 st
KiB Mem :  8269412 total,  3161228 free,  4878832 used,   229352 buff/cache
KiB Swap: 15483260 total, 14830144 free,   653116 used.  3256848 avail Mem
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0    8936    192    148 S   0  0   0:17 init
    8 root      20   0    8936     96     56 S   0  0   0:00 init

清理僵尸进程

我们不能真正杀死僵尸进程,因为它已经死了。但是,我们可以使用一些变通方法来清理僵尸进程。

使用SIGCHLD信号

我们可以手动向僵尸进程的父进程发送SIGCHLD信号。因此,它会通知父进程触发wait()系统调用,这将从进程表中清除已失效的子进程。

找到已失效进程的父 ID:

代码语言:javascript
复制
$ ps -A -ostat,pid,ppid | grep -e '[zZ]'
Z      108   103

这列出了僵尸进程的STAT列、进程 ID父进程 ID。接下来使用kill命令向父进程发送SIGCHLD信号:

代码语言:javascript
复制
kill -s SIGCHLD 103

但是,并不能真正保证向父进程发送SIGCHLD信号会杀死僵尸进程。它仅适用于父进程可以处理SIGCHLD信号的情况。

杀死父进程

如果上面无法清除已失效的进程,我们应该考虑杀死其父进程:

代码语言:javascript
复制
kill -9 103

103是已失效进程的父 ID

但是,杀死父进程会影响其所有子进程。因此,我们应该格外小心,并且必须在杀死父进程之前确定影响。

如果存在很多僵尸进程,或者如果僵尸进程的父进程是init进程(pid=1),我们也可以考虑重启系统。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 入门小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是僵尸进程
  • 进程状态
  • 僵尸进程的创建
  • 僵尸进程的识别
  • 清理僵尸进程
  • 使用SIGCHLD信号
  • 杀死父进程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档