走进Linux的世界:进程状态
嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的
passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let’s go!
我的博客:yuanManGan
我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记 闲言碎语小记坊 进阶数据结构 走进Linux的世界 题山采玉 领略算法真谛

进程状态
1. linux内核源代码怎么说
为了弄明⽩正在运⾏的进程是什么意思,我们需要知道进程的不同状态。⼀个进程可以有⼏个状态(在Linux内核⾥,进程有时候也叫做任务)。
下⾯的状态在kernel源代码⾥定义:
/*
*The task state array is a strange "bitmap" of
*reasons to sleep. Thus "running" is zero, and
*you can test for combinations of others with
*simple bit tests.
*/
static const char *const task_state_array[] = {
"R (running)", /*0 */
"S (sleeping)", /*1 */
"D (disk sleep)", /*2 */
"T (stopped)", /*4 */
"t (tracing stop)", /*8 */
"X (dead)", /*16 */
"Z (zombie)", /*32 */
}
在linux内核中每一种状态就对应一个数字,使用二进制的数字,能更好进行位计算,
2.进程状态查看
1 ps aux / ps axj 命令
- a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
- x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
- j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息
- u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等
3.R运行状态(running)
R运⾏状态(running): 并不意味着进程⼀定在运⾏中,它表明进程要么是在运⾏中要么在运⾏队列⾥。
我们为了方便管理进程,有一个运行队列,里面的进程以链表的形式连接在一起,依旧调度算法等待cpu进行调度。
我们将在运行队列的进程的状态定义为R状态。
//myprocess.c1 #include <stdio.h>2 #include <unistd.h>3 4 int main() 5 {6 7 while(1)8 {9 10 }11 12 return 0;13 }
执行这个代码然后查看进程就能看到R状态

4.S睡眠状态(sleeping)
S睡眠状态(sleeping): 意味着进程在等待事件完成(这⾥的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
当我们一个进程在等待时,比如等待你输入时,它就会从运行队列进入等待队列,等待你就绪后才会重新进入运行队列。
即在运行队列里的进程的状态是运行状态,在等待队列里面的进程的状态是睡眠状态。
1 #include <stdio.h>2 #include <unistd.h>3 4 int main()5 {6 int a;7 scanf("%d", &a);8 9 printf("a = %d\n", a);10 11 12 return 0;13 }

5.D磁盘休眠状态(Disk sleep)
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
D状态的进程它不会被kill命令和os杀死。
比如你是一个银行的操作系统,你的cpu的内存已经快满了,os必须要选择性的杀死某些进程,不然整个os系统挂掉了的危害是很大了,那我们的重要的进程,比如一个进程里面记录了一个月的交易记录,这个进程就要处于D状态不让os杀死它。
这个状态不好模拟就先不模拟了。
6.T/t停止状态(stopped)
T停⽌状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停⽌(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运⾏。
T 状态:进程被主动要求暂停执行,通常是由于用户操作或调试需求。
S 状态:进程在等待某个事件发生(如 I/O 完成、信号、定时器到期等),它是被动的。
我们可以使用kill -19让进程进入T状态。使用kill -18恢复。

注意我们恢复后的进程就不是前台进程而变成了后台进程了。
而我们的t状态就是专门为调试准备的,T和t的是没有区别的,主要是调试太重要了,专门为它弄个状态。

7.僵尸状态Z(zombie) 和X死亡状态(dead)
- 僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程
- 僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
- 所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态
来⼀个创建维持30秒的僵死进程例⼦:
#include <stdio.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id > 0){ //parentprintf("parent[%d] is sleeping...\n", getpid());sleep(30);}else{printf("child[%d] is begin Z...\n", getpid());sleep(5);exit(EXIT_SUCCESS);}return 0;
}

X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。
8.孤儿进程
- ⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?
- ⽗进程先退出,⼦进程就称之为“孤⼉进程”
- 孤⼉进程被1号init进程领养,当然要有init进程回收喽。


一路跟着敲代码、查状态,相信你已经对 Linux 进程状态了如指掌啦!从内核源码里的位图状态定义,到终端里 ps 命令下的 R/S/D/T/Z 标识,我们用 “理论 + 实操” 的方式,拆透了每个状态的本质:
- 运行状态 R 是 “就绪或正在运行” 的待命者,睡眠状态 S 是 “等待事件” 的休眠者;
- 不可中断的 D 状态是守护关键任务的 “守护者”,T/t 状态是可主动暂停、方便调试的 “暂停键”;
僵尸进程 Z 是等待父进程 “收尸” 的残留,孤儿进程则会被 init 进程温柔领养。
这些状态不是孤立的,背后是 Linux 内核的调度智慧 —— 用合理的状态管理,让 CPU 资源物尽其用,同时保证系统稳定。掌握了状态切换的命令(如 kill -19/-18)和模拟方法,以后遇到进程无响应、僵尸进程等问题,也能快速定位根源~
编程的乐趣就在于 “知其然,更知其所以然”,希望这篇文章能成为你 Linux 学习路上的一块垫脚石。如果觉得有收获,不妨点赞收藏,也可以逛逛我的专栏,后续还会分享更多 Linux 干货和编程技巧~ 让我们继续在代码的世界里探险,解锁更多技能吧!💻✨


