进程:概念、PCB 与进程状态机
进程是"执行中的程序"加上它所占资源的封装,是操作系统进行资源分配的基本单位;内核用进程控制块(PCB)记录它的全部元数据。
一句话定义
进程是"执行中的程序"加上它所占资源的封装,是操作系统进行资源分配的基本单位;内核用进程控制块(PCB)记录它的全部元数据。
为什么重要
进程是操作系统三大抽象中的第一个,也是用户可见的最重要抽象。理解"程序是静态文件、进程是动态实体"的区别,是理解调度、隔离、IPC 的一切前提;日常排查中"进程状态是什么"往往就是问题的第一步线索。
前置知识
kp-003(进程的创建与退出都是系统调用)。
核心概念
- 程序 vs 进程:程序是磁盘上的可执行文件(静态),进程是它的一次运行实例(动态),同一程序可同时对应多个进程。
- PCB(Process Control Block):内核中描述进程的结构体,Linux 里即
task_struct。 - PID:进程标识符,
/proc/<pid>目录是内核把 PCB 部分信息暴露给用户的窗口。 - 五状态模型:新建、就绪、运行、阻塞、终止。
原理与机制
PCB 的典型字段:进程 ID 与父进程 ID、CPU 上下文(寄存器快照、程序计数器)、进程状态、内存描述符(页表指针)、打开文件表、信号处理表、凭证(uid/gid)、调度信息(优先级、时间片)。
五状态机的转移规则:
创建 被调度器选中
新建 -----------> 就绪 ------------------> 运行
^ <------------------ |
| 时间片用尽/被抢占 |
| | 等待 I/O 或事件
| I/O 完成/事件到达 v
+--------------------- 阻塞
运行 -------> 终止 (exit 后保留 PCB 成为僵尸,直到父进程 wait)
三个易混淆点:运行到就绪是"被抢占"(非自愿),运行到阻塞是"主动等待 I/O";阻塞进程不参与 CPU 竞争,事件到达后才回到就绪;终止后的进程在父进程回收前以僵尸态存在(详见 kp-007)。
图示
状态与资源的对应:就绪队列排队的是"CPU 使用权",阻塞队列挂在具体设备或事件上——一个进程可能同时"不在就绪队列、而在磁盘等待队列"。
直观类比
进程像一张在医院就诊的病人档案(PCB):病历记录着全部状态;病人要么在候诊区(就绪)等着叫号上 CPU(诊室),要么去做检查(阻塞 I/O),检查完回到候诊区,最后离院(终止)但档案要等结算(wait)后才销毁。
实例或案例
ps aux # 看全系统进程,STAT 列即状态:R 运行/就绪、S 可中断睡眠、D 不可中断睡眠、Z 僵尸
cat /proc/self/status # 当前 shell 的状态、上下文切换计数(macOS 用 ps 命令替代)
sleep 300 & ps -o stat,pid,cmd -C sleep # 观察一个睡眠态进程
D 状态(不可中断睡眠)常出现在 NFS 卡住或磁盘故障时,kill -9 都杀不掉它,这正是"阻塞不等于运行也不等于僵尸"的活教材。
常见误区
- 认为进程数越多 CPU 利用率越高:阻塞态进程根本不占 CPU,利用率取决于就绪队列的长度与切换开销。
- 混淆僵尸与孤儿:僵尸是"已死未被收尸"(父进程没 wait),孤儿是"父进程先死"(被 init/systemd 收养,无害)。
- 认为
/proc里的信息是应用自己写的:全部来自内核的 PCB。
与其他知识点的关系
kp-006 讲状态机里"运行/就绪"之间切换的具体动作;kp-010 讲"谁从就绪队列里被选中";kp-007 讲新建与终止两条边上的系统调用。
延伸阅读
《操作系统概念》第 3 章;man 5 proc。
自测题
- 程序和进程的区别是什么?
答:程序是磁盘上的静态可执行文件;进程是该程序的一次动态执行实例,拥有独立的地址空间、PCB 与运行状态。
- 进程从"运行"回到"就绪"和进入"阻塞"的本质区别?
答:前者是非自愿地被剥夺 CPU(时间片用尽或被更高优先级抢占),仍是 CPU 候选;后者是主动等待 I/O/事件,在事件到来前不再参与 CPU 竞争。
- 僵尸进程为什么存在?
答:内核必须保留已退出进程的退出码等 PCB 信息,直到父进程调用 wait 读取;收尸机制未发生,僵尸就持续存在。