Linux 进程状态 R/S/D/Z/T 含义与排查思路

举报
yd_220030742 发表于 2026/10/25 10:44:58 2026/10/25
【摘要】 梳理 Linux 进程 R/S/D/Z/T 五种常见状态的含义,介绍用 ps、top、/proc 查看状态的方法,以及进程长时间处于 D 状态和出现大量僵尸进程时的排查思路。

在日常的 Linux 运维和开发中,我们经常会遇到“机器很卡但 CPU 不高”“进程杀不掉”“系统里堆满了僵尸进程”之类的问题。要定位这些问题,首先要读懂进程状态。本文基于 Linux 内核文档和常用工具的通用行为,梳理 R、S、D、Z、T 这几种常见状态的含义,并给出排查思路和命令示例,方便日常查阅。

一、为什么要关注进程状态

Linux 中每个进程(准确说是任务)在任意时刻都处于某一种状态,内核调度器根据状态决定它能否获得 CPU。通过 ps、top 等工具可以看到状态字段(STAT 或 S 列)。系统负载(load average)也与状态直接相关:它统计的是处于可运行状态(R)和不可中断睡眠状态(D)的任务数量,因此“负载高但 CPU 空闲”往往意味着有大量进程卡在 D 状态,等待磁盘或网络等 IO。

二、常见进程状态详解

1. R(Running / Runnable):运行或可运行

R 表示进程正在 CPU 上执行,或者已经就绪、正在运行队列中等待调度。R 状态的进程数量持续大于 CPU 核数,说明 CPU 资源紧张。常见原因包括死循环、计算密集型任务、线程数过多等。排查时可以结合 top 的 %CPU 排序,再用 perf 或 pstack 等工具查看热点函数。

2. S(Interruptible Sleep):可中断睡眠

S 表示进程在等待某个事件,例如等待网络数据、等待定时器、等待锁或等待用户输入。这类睡眠可以被信号或事件唤醒,是最常见的状态,绝大多数空闲的服务进程都处于 S 状态,属于正常现象,不必担心。

3. D(Uninterruptible Sleep):不可中断睡眠

D 表示进程在等待内核中的某个操作完成,通常是磁盘 IO、NFS 网络文件系统响应或某些驱动操作。处于 D 状态时进程不响应信号,连 kill -9 也无法立刻结束它。短暂的 D 状态是正常的,但如果长时间停留,往往意味着存储故障、NFS 服务端不可达、磁盘坏道或驱动问题,需要重点排查。

4. Z(Zombie):僵尸进程

子进程已经退出,但父进程还没有调用 wait 系列函数回收它的退出状态,此时子进程只保留一个进程表项,状态显示为 Z,命令列通常带有 defunct 标记。僵尸进程不占用 CPU 和内存,但占用进程号(PID)。如果数量不断增加,可能耗尽 PID 资源,导致无法创建新进程。

5. T(Stopped / Traced):停止或被跟踪

T 表示进程被信号暂停(例如 SIGSTOP、SIGTSTP,即在终端按下 Ctrl+Z),或者正在被调试器(gdb、strace)跟踪。使用 kill -CONT 可以让被停止的进程继续运行。如果发现服务进程莫名处于 T 状态,要检查是否有人误按了 Ctrl+Z 或遗留了调试会话。

三、使用 ps 和 top 查看进程状态

最常用的方式是 ps 命令,STAT 列的第一个字母就是进程状态,后面的附加字符含义如下:s 表示会话首进程,l 表示多线程,+ 表示前台进程组,N 表示低优先级,< 表示高优先级。示例如下:

# 查看所有进程及状态
ps aux
# 只看状态为 D 或 Z 的进程
ps -eo pid,ppid,stat,wchan:32,cmd | awk '$3 ~ /^[DZ]/'
# 统计各状态数量
ps -eo stat | cut -c1 | sort | uniq -c

top 中的 S 列同样显示状态,顶部的 Tasks 行会汇总 running、sleeping、stopped、zombie 的数量,可以快速判断系统整体情况。按 P 按 CPU 排序,按 M 按内存排序。也可以直接查看 /proc 目录获取更详细的信息:

# 查看某进程状态和内核等待函数
cat /proc/<PID>/status | grep -E "State|PPid"
cat /proc/<PID>/wchan; echo
cat /proc/<PID>/stack   # 需要 root 权限

四、进程长时间处于 D 状态怎么办

第一步,确认是否真的长时间卡住。多次执行 ps 观察同一个 PID 是否持续处于 D 状态,而不是偶尔一次的瞬时状态。第二步,通过 wchan 或 /proc/PID/stack 查看进程卡在哪个内核函数,判断是文件系统、块设备还是网络存储。第三步,使用 iostat -x 1、iotop、vmstat 1 观察磁盘利用率、await 延迟和 wa 比例;用 dmesg -T 查看是否有磁盘报错、超时或 hung task 的提示。

iostat -x 1 3
vmstat 1 5
dmesg -T | grep -iE "hung|timeout|I/O error"
mount | grep nfs

第四步,根据原因处理:如果是 NFS 服务端不可达,需要恢复网络或服务端,必要时使用 umount -f 或 umount -l 处理挂载点;如果是磁盘故障,需要检查硬件并迁移数据;如果是驱动或内核问题,则需要升级内核或驱动。需要注意的是,D 状态的进程通常无法被 kill 掉,强行重启往往只是最后手段,应优先解决底层 IO 问题。

五、出现大量僵尸进程怎么办

僵尸进程本身已经死亡,所以对它执行 kill 是没有效果的,关键在于它的父进程。处理思路如下:先用 ps 找到僵尸进程的父进程 PID,再判断父进程为什么没有回收子进程。

# 找出僵尸进程及其父进程
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'
# 向父进程发送 SIGCHLD,提示其回收子进程
kill -s SIGCHLD <PPID>

如果父进程是自己开发的程序,应检查代码是否正确处理了 SIGCHLD 信号,或者在合适的位置调用 wait / waitpid;也可以在创建子进程时使用双重 fork 或将 SIGCHLD 设置为忽略。如果发送 SIGCHLD 后仍无效,可以在业务允许的情况下重启父进程,此时僵尸进程会被 init(PID 1)接管并回收。在容器场景中,如果容器内的 PID 1 进程不负责回收子进程,也容易积累僵尸进程,可以使用 tini 之类的轻量 init 作为入口进程。

六、T 状态与 R 状态的简单处理

对于被暂停的进程,可以使用 kill -CONT PID 恢复运行,或者用 fg、bg 命令恢复终端中的任务。对于 CPU 占用过高的 R 状态进程,可以先用 top -H -p PID 找到占用最高的线程,再结合 jstack、pstack、perf top 等工具分析具体代码位置,确认是业务正常高负载还是程序缺陷。

七、小结

总结一下:R 代表在运行或等待 CPU,S 是正常的等待事件,D 是等待 IO 且不可被信号中断,Z 是已退出但未被父进程回收,T 是被暂停或被调试。排查问题时,建议遵循“先看整体、再看单个进程、最后看内核等待点”的顺序:先用 top、uptime 看负载和各状态数量,再用 ps 过滤异常状态,最后借助 /proc、iostat、dmesg 等工具定位根因。熟悉这些状态的含义,可以让我们在遇到系统卡顿、进程无法结束等问题时更快地缩小排查范围。以上内容为通用知识整理,具体命令输出可能因发行版和内核版本略有差异,实际操作前请在测试环境中验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。