R表示运行或可运行,S为可中断睡眠,D为不可中断睡眠,Z是僵尸进程,T是已停止或被追踪。它们对应内核task_struct的state字段,反映进程实时调度状态。

进程状态码 R、S、D、Z、T 分别代表什么
Linux ps 或 top 输出里的单字母状态码,是理解进程行为的关键入口。它们不是抽象概念,而是内核 task_struct 中 state 字段的直观映射:
-
R:正在运行(running)或可立即运行(runnable),在就绪队列中排队等 CPU;不等于“正在执行指令”,也包含刚被唤醒未上 CPU 的瞬间 -
S:可中断睡眠(interruptible sleep),等待某事件(如磁盘 I/O 完成、信号、互斥锁释放),能被信号打断并提前退出等待 -
D:不可中断睡眠(uninterruptible sleep),通常卡在内核态底层操作(如块设备驱动、NFS 服务器无响应),不能被任何信号终止,kill -9 也无效 -
Z:僵尸进程(zombie),子进程已退出但父进程尚未调用wait()回收其退出状态,只保留一个 task_struct 结构,不占内存也不执行,但会占用 PID -
T:已停止(stopped)或被追踪(traced),常见于kill -STOP、调试器断点触发、ptrace附加时
为什么 ps 看不到 D 状态进程的堆栈,且无法 kill
D 状态本质是进程阻塞在内核函数里,尚未返回用户空间,因此无法响应信号处理逻辑——信号机制本身依赖进程回到用户态执行 signal handler,而 D 状态下连调度器都绕过它。
- 典型诱因:硬盘故障导致 I/O 请求长期挂起、NFS 服务器宕机且客户端未设超时、某些驱动 bug(如旧版 RAID 卡驱动)
-
/proc/对 D 进程可能为空或只显示极短内核路径(如/stack __rq_wait_event),因为尚未进入完整调用链 - 唯一可靠解法是修复底层资源(如拔掉坏盘、重启 NFS 服务),或重启系统;强行 reboot 可能比等待更早恢复服务
如何区分真正的僵尸进程和 ps 显示异常
Z 状态进程本身无害,但大量存在说明父进程有 bug(未调用 waitpid())或设计缺陷(如 fork 后忘记 wait)。不过要注意误判场景:
KgShop,是国内一款快速/稳定/安全的开源电子商城系统,采用linux,mysql,srutsEX,hibernate,ejb3等技术,Kghop第一版诞生于2010年,经过多年开发,Kgshop系统已拥有快速、稳定、支持大量并发访问等软件特性,是10万人在线的JAVA商城优秀解决方案。KgShop拥有良好的模板机制,易于进行二次开发。Kgshop每一行代码都经过严谨的测试,汇聚大批工程师多年
- 用
ps aux | grep ' Z '精确匹配空格包围的Z,避免匹配到含Z的命令行参数 - 检查
/proc/第三列:若为/stat Z且第八列(PPid)为1,说明 init(systemd)已接管但仍未回收——这通常是父进程 exit 前就崩溃,由内核托孤所致 - 真实僵尸不会消耗 CPU 或内存,
ps显示的 RSS/VSZ 均为 0;若看到非零值,大概率是 ps 解析 /proc 出错,或进程刚退出、状态尚未刷新
用 pidstat 和 /proc/pid/status 挖掘更细粒度状态信息
ps 的单字母太粗略,真正排查需深入内核暴露的细节。比如:
-
pidstat -w -p可观察每秒上下文切换次数,若1 D进程伴随极高 cswch/s,说明频繁被唤醒又立刻阻塞,可能是驱动轮询逻辑异常 -
cat /proc/:其中/status | grep -E 'State|tgid|ppid|SigQ' State行末括号内是更准确的状态描述(如sleeping in nanosleep),SigQ显示待处理信号数,高值配合T状态说明信号积压未处理 -
cat /proc/在非 D 状态下可看完整内核调用栈,但需确保内核编译开启/stack CONFIG_STACKTRACE,否则为空
进程状态不是静态快照,而是内核调度器与硬件交互的实时投影。最易被忽略的是:同一进程在 ps 刷新间隔内可能跨越多个状态(如 R→S→R),而工具采样只能捕获瞬时值——所以反复观察、结合 I/O 和 CPU 指标交叉验证,比单次截图更有价值。







