什么是进程控制块(PCB)?进程存在的唯一标志是什么
这是“操作系统系列教程”的第七篇。上一篇我们讲了进程,知道了它是操作系统分配资源的基本单位。但操作系统到底是怎么“记住”一个进程的?它怎么知道有哪些进程、每个进程处于什么状态、该用哪些资源?答案就藏在一个关键的数据结构里——进程控制块(PCB)。
操作系统如何“记住”一个进程?
先来想一个问题:操作系统同时管理着几十上百个进程,它怎么知道每个进程的存在?
当你打开任务管理器,看到一长串进程列表,每个进程都有 PID、内存占用、CPU 占用、状态等信息。这些信息不是凭空产生的,而是操作系统在创建进程时,为每个进程建立了一份“档案”。这份档案,就是进程控制块(Process Control Block,PCB)。
没有 PCB,操作系统就无法感知进程的存在。进程一旦创建,PCB 也随之建立;进程一旦终止,PCB 也随之销毁。可以说,PCB 是进程存在的唯一标志。
这篇文章,我们就来把 PCB 这件事讲清楚。
说明:本文涉及数据结构、操作系统内部实现等知识。初学者如果遇到暂时看不懂的术语,可以先跳过细节,重点理解“PCB 是操作系统管理进程的唯一依据,记录了进程的所有信息”这一核心思想。
一、PCB 到底是什么?
1.1 从生活场景理解
我们可以用“学生档案”来类比 PCB。
| 学校场景 | 操作系统 |
|---|---|
| 学生 | 进程 |
| 学生档案 | PCB |
| 档案中的姓名、学号、班级 | PID、进程状态、优先级 |
| 档案中的成绩单 | CPU 使用时间、内存占用 |
| 档案管理员 | 操作系统内核 |
学校要管理学生,必须为每个学生建立档案。档案里记录了学生的所有信息,学校通过档案来了解学生、管理学生。同样,操作系统要管理进程,必须为每个进程建立 PCB,通过 PCB 来感知进程、调度进程、分配资源。
1.2 PCB 的定义
给出一个正式的定义:
进程控制块(PCB)是操作系统为了管理进程而创建的一个数据结构,它记录了进程的所有信息,是进程存在的唯一标志。
这个定义里有三个关键点:
- 数据结构:PCB 本质上是一个结构体,包含多个字段;
- 记录所有信息:进程的标识、状态、资源、优先级等都在 PCB 中;
- 唯一标志:操作系统通过 PCB 来感知进程的存在,没有 PCB 就没有进程。
1.3 PCB 在系统中的位置
图 1:PCB 在系统中的位置。 PCB 是内核中的数据结构,记录了进程的所有信息,是操作系统管理进程的唯一依据。
从图 1 可以看出,PCB 并不在进程的用户空间里,而是位于内核空间。进程本身可能只能访问自己的代码、数据、堆、栈,但 PCB 由内核维护,进程无法直接修改。
二、为什么需要 PCB?
2.1 没有 PCB 会怎样?
假设操作系统没有 PCB,会发生什么?
- 操作系统不知道有哪些进程存在;
- 不知道每个进程处于什么状态;
- 不知道每个进程占用了哪些资源;
- 不知道下一个该调度哪个进程;
- 进程切换时,不知道保存和恢复什么信息。
没有 PCB,操作系统就像没有档案的学校,完全无法管理学生。进程将变成一团乱麻,系统无法正常运转。
2.2 PCB 的核心作用
PCB 的作用可以归纳为四个方面:
| 作用 | 说明 |
|---|---|
| 标识进程 | 通过 PID 唯一标识每个进程 |
| 记录状态 | 记录进程当前处于就绪、运行还是阻塞 |
| 保存上下文 | 进程切换时保存和恢复 CPU 寄存器、程序计数器等 |
| 管理资源 | 记录进程占用的内存、打开的文件、使用的设备等 |

图 2:PCB 的四大核心作用。 标识、记录、保存、管理。
三、PCB 包含哪些信息?
PCB 中到底存了哪些东西?不同操作系统的实现略有差异,但核心信息大致相同。我们可以把它分为以下几类。
3.1 进程标识信息
| 字段 | 说明 |
|---|---|
| 进程 ID(PID) | 唯一标识一个进程 |
| 父进程 ID(PPID) | 创建该进程的父进程 ID |
| 用户 ID(UID) | 启动该进程的用户 |
| 组 ID(GID) | 用户所属的组 |
3.2 进程状态信息
| 字段 | 说明 |
|---|---|
| 进程状态 | 新建、就绪、运行、阻塞、终止 |
| 优先级 | 调度优先级 |
| 时间片 | 剩余可执行时间 |
| 等待事件 | 阻塞时等待的事件类型 |
3.3 CPU 上下文信息
| 字段 | 说明 |
|---|---|
| 程序计数器(PC) | 下一条要执行的指令地址 |
| 通用寄存器 | 保存进程执行时的寄存器值 |
| 栈指针(SP) | 指向当前栈顶 |
| 程序状态字(PSW) | 标志位、特权级等 |
3.4 内存管理信息
| 字段 | 说明 |
|---|---|
| 页表基址 | 指向该进程的页表 |
| 内存限制 | 代码段、数据段、堆、栈的边界 |
| 内存占用 | 已分配的内存大小 |
3.5 文件与设备信息
| 字段 | 说明 |
|---|---|
| 打开文件列表 | 该进程打开的所有文件 |
| 文件描述符表 | 文件描述符到文件对象的映射 |
| 设备列表 | 该进程占用的设备 |
3.6 统计与调度信息
| 字段 | 说明 |
|---|---|
| CPU 使用时间 | 进程累计占用的 CPU 时间 |
| 启动时间 | 进程创建的时间 |
| 子进程列表 | 该进程创建的子进程 |
| 信号处理 | 信号处理函数的地址 |
图 3:PCB 的主要内容。 六大类信息,覆盖进程管理的方方面面。
四、PCB 的组织方式
系统中同时存在很多进程,也就有很多 PCB。操作系统如何组织这些 PCB,才能高效地查找、插入、删除?
常见的组织方式有三种:链表、索引表、队列。
4.1 链表方式
把所有 PCB 用链表串起来,操作系统通过遍历链表来查找进程。

图 4:PCB 链表组织方式。 通过指针把 PCB 串联起来。
优点:实现简单,插入删除方便。
缺点:查找效率低,需要遍历。
4.2 索引表方式
操作系统维护一张索引表,表中每一项指向一个 PCB。通过 PID 可以直接定位到 PCB。

图 5:PCB 索引表组织方式。 通过 PID 直接定位 PCB,查找效率高。
优点:查找效率高,O(1) 时间复杂度。
缺点:需要额外的索引表空间。
4.3 队列方式
按照进程状态,把 PCB 放入不同的队列:就绪队列、阻塞队列、运行队列等。

图 6:PCB 队列组织方式。 按状态分队列,调度器直接从对应队列中选取进程。
优点:调度方便,直接操作对应队列。
缺点:状态转换时需要移动 PCB。
在实际操作系统中,这三种方式通常会结合使用。例如,Linux 使用链表和红黑树来组织 PCB,同时维护多个队列来支持调度。
五、Linux 中的 PCB:task_struct
在 Linux 中,PCB 对应的数据结构是 task_struct。它是一个非常庞大的结构体,定义在 include/linux/sched.h 中。
5.1 task_struct 的主要字段
| 字段 | 说明 |
|---|---|
pid | 进程 ID |
state | 进程状态 |
prio | 调度优先级 |
mm | 内存管理信息 |
files | 打开文件信息 |
thread | CPU 上下文 |
parent | 父进程指针 |
children | 子进程链表 |
5.2 task_struct 的规模
task_struct 的大小在不同内核版本中有所不同,通常在几 KB 到十几 KB 之间。它包含了进程的所有信息,是内核中最重要的数据结构之一。
你可以用下面的命令查看 Linux 内核中 task_struct 的定义:
grep -n "struct task_struct" /usr/src/linux-headers-$(uname -r)/include/linux/sched.h
5.3 进程与 PCB 的对应关系
在 Linux 中,每个进程有且只有一个 task_struct。内核通过 task_struct 来管理进程的一切。

图 7:Linux 中进程与 task_struct 的对应关系。 每个进程对应一个 task_struct。
六、PCB 与进程状态转换
进程状态的变化,本质上就是 PCB 中状态字段的变化。当进程从就绪变为运行,PCB 中的状态字段从“就绪”改为“运行”;当进程从运行变为阻塞,状态字段从“运行”改为“阻塞”。

图 8:进程状态转换与 PCB。 状态变化时,PCB 中的状态字段和所在队列都会更新。
从图 8 可以看出,PCB 不仅记录了进程状态,还通过队列组织方式,帮助操作系统快速找到对应状态的进程。
七、PCB 的创建与销毁
7.1 PCB 的创建
当创建一个新进程时,操作系统会:
- 分配一个空闲的 PCB;
- 填写 PCB 中的各个字段;
- 把 PCB 插入就绪队列;
- 分配 PID;
- 分配内存等资源。

图 9:PCB 的创建过程。 从分配 PCB 到插入就绪队列。
7.2 PCB 的销毁
当进程终止时,操作系统会:
- 回收进程占用的内存、文件等资源;
- 把 PCB 从队列中移除;
- 释放 PCB;
- 通知父进程。
如果父进程没有及时回收,PCB 会保留,形成僵尸进程。僵尸进程占用的主要就是 PCB 资源。
八、常见误区澄清
| 误区 | 真相 |
|---|---|
| “PCB 是进程的一部分” | PCB 位于内核空间,由内核维护,不属于进程的用户空间 |
| “没有 PCB 进程也能运行” | PCB 是进程存在的唯一标志,没有 PCB 就没有进程 |
| “PCB 只记录 PID” | PCB 记录了进程的所有信息,包括状态、上下文、资源等 |
| “PCB 越大越好” | PCB 过大会浪费内存,需要在信息完整和空间效率之间平衡 |
| “进程终止后 PCB 立即消失” | 如果父进程未回收,PCB 会保留,形成僵尸进程 |
| “所有操作系统的 PCB 都一样” | Linux 用 task_struct,Windows 用 EPROCESS,结构不同 |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)