一、什么是进程
我们写的程序只是静态的文件,存在硬盘上。
只有当它被操作系统加载到内存,CPU 开始执行它的指令时,这个“活起来”的程序才叫进程(Process)。
可以这么理解:
程序是菜谱,进程是正在做菜的厨师。
- 菜谱放在书架上(硬盘),不会自己动;
- 当厨师(CPU)拿着菜谱进厨房(内存)开始做菜时,这一顿饭的制作过程,就是程序的运行实例,也就是进程。
二、CPU 不等人:并发的出现
当进程执行到“读硬盘文件”这一步时,它必须等硬盘返回数据。
但硬盘速度太慢,CPU 如果傻等,就浪费了计算能力。
于是,操作系统采用了「切换」机制:
- 当进程 A 在等硬盘数据时,CPU 转去执行进程 B;
- 等数据到了,系统用中断通知 CPU 回来继续执行 A。
这就像你煮水壶时不会傻等,而是趁水烧开的空隙去扫地、擦桌子。
CPU 也是一样,一直让自己忙碌起来。
于是出现了两个重要概念:
- 并发(Concurrency):一个 CPU 快速切换执行多个任务,看起来“同时”运行;
- 并行(Parallelism):多个 CPU 真正同时执行多个任务。
👉 单核 CPU 只能并发,多核 CPU 才能并行。
三、进程与程序的关系
继续用生活例子:
男生要做“辣子鸡”,他打开菜谱、买食材、动手炒菜。
过程中,女生突然让他去买可乐。
于是男生:
- 在菜谱上做个标记“做到哪一步了”(保存状态);
- 去买可乐(切换到另一个任务);
- 回来后,按标记接着炒菜(恢复状态)。
这就是进程切换的本质:
CPU 在不同进程之间切换执行,每次切换都要保存与恢复现场。
四、进程的三大基本状态
在操作系统里,进程不是一直在“跑”,它会在几种状态之间切换:
|
状态 |
含义 |
|
运行(Running) |
正在被 CPU 执行 |
|
就绪(Ready) |
等待 CPU 时间片,随时可以运行 |
|
阻塞(Blocked) |
等待某事件(I/O 完成、信号等) |
这三个状态不断循环,形成“运行—暂停—运行”的规律。
例如:
- A 进程正在运行(Running)
- 时间片到了,被切换出去(Ready)
- A 要读文件,进入等待状态(Blocked)
- 文件读完,A 再次进入就绪队列(Ready)
五、五种+两种扩展状态
除了运行、就绪、阻塞外,还有两个基本状态:
|
状态 |
含义 |
|
创建(New) |
进程正在被系统初始化 |
|
结束(Exit) |
进程执行完或出错被销毁 |
而在拥有虚拟内存的系统中,还可能出现两种“挂起”状态:
|
状态 |
含义 |
|
阻塞挂起(Blocked-Suspended) |
进程在硬盘上,等待事件发生 |
|
就绪挂起(Ready-Suspended) |
进程在硬盘上,一旦调入内存即可运行 |
为什么要挂起?
因为内存有限,不能让那些“在等事”的进程一直占着空间。
于是操作系统把它们暂时“赶”到硬盘上,等需要再“叫回来”。
六、进程控制块(PCB)
每个进程在系统中都有一张“身份证”——进程控制块(PCB)。
它是内核中记录进程全部信息的数据结构,进程存在,PCB 必存在。
PCB 包含的信息:
- 进程描述信息
-
- PID(进程号)
- 用户 ID(归属用户)
- 进程控制信息
-
- 状态(new、ready、running、waiting)
- 优先级(调度依据)
- 资源清单
-
- 打开的文件、I/O 设备
- 内存地址空间
- CPU 上下文
-
- 各种寄存器的值(保存运行现场)
可以理解为:PCB 是进程的档案袋,记录了“它是谁、它干什么、干到哪了”。
PCB 的组织形式:
PCB 通常用链表组织,比如:
- 就绪队列:所有等待 CPU 的进程;
- 阻塞队列:所有等待事件的进程。
如下图(思维导图式):

这样,调度器可以方便地在不同队列之间移动进程。
七、进程的生命周期(四个关键动作)
1. 创建进程
由父进程发起,用于启动一个新任务。
过程如下:
- 分配一个 PCB;
- 初始化基本信息;
- 分配内存等资源;
- 放入就绪队列等待执行。
2. 终止进程
三种方式:
- 正常结束;
- 异常结束;
- 外界干预(
kill)。
当父进程被终止时,它的子进程会变为孤儿,由系统的 init(1号进程)收养。
3. 阻塞进程
进程需要等待某事件(如 I/O)时,会主动调用阻塞语句:
- 改变状态为 Blocked;
- 保存上下文;
- 放入阻塞队列。
4. 唤醒进程
当等待事件发生时(如 I/O 完成):
- 从阻塞队列移出;
- 状态改为 Ready;
- 放入就绪队列等待 CPU 调度。
阻塞与唤醒是一对反向操作,常用于多进程协作。
八、进程上下文与切换
1. CPU 上下文是什么?
CPU 在执行任务时,依赖两类关键信息:
- 寄存器(Register):保存当前计算状态(像口袋里的工具);
- 程序计数器(PC):记录下一条指令地址。
这两者合起来,就是 CPU 的“工作现场”。
当要切换任务时,操作系统必须:
- 保存当前任务的寄存器 + 程序计数器;
- 加载新任务的寄存器 + 程序计数器;
- 跳转到新任务继续执行。
这就是所谓的CPU 上下文切换。
2. 进程上下文切换是什么?
进程的切换更复杂:
- 不仅要保存/恢复寄存器和 PC;
- 还要切换虚拟内存、栈、内核堆栈等信息。
操作系统会把这些数据都记录在 PCB 中:
保存当前进程 → PCB_A
从 PCB_B 取出状态 → 恢复 CPU 环境
然后 CPU 从中断点继续执行另一个进程。
3. 什么时候会切换?
发生进程上下文切换的常见场景有:
- 时间片用完
操作系统切换到下一个就绪进程(公平调度)。 - 资源不足
比如内存不够,当前进程被挂起。 - 主动睡眠
调用sleep()等函数。 - 高优先级进程到来
抢占 CPU,低优先级进程被暂停。 - 硬件中断
比如键盘、网卡中断,会打断当前进程。
九、切换的代价
每次上下文切换都要:
- 保存/恢复寄存器;
- 更新内核栈;
- 修改页表;
- 刷新 CPU Cache。
这些都很耗时!
所以切换太频繁会让 CPU 花更多时间在“换人”,而不是“干活”。
理想的系统状态是:进程切得少,CPU 干得多。
十、核心总结
|
概念 |
解释 |
|
进程 |
程序运行的实例,是资源分配的基本单位 |
|
线程 |
进程内的执行单元,是 CPU 调度的基本单位 |
|
PCB |
记录进程全部状态的控制块 |
|
状态切换 |
运行 ↔ 就绪 ↔ 阻塞(附带创建与终止) |
|
上下文切换 |
保存现场、恢复现场,实现多任务并发 |
|
并发 vs 并行 |
单核交替执行 vs 多核同时执行 |
十一、形象总结:做饭类比复盘
|
操作系统概念 |
做饭类比 |
|
程序 |
菜谱(静态) |
|
进程 |
厨师(运行中任务) |
|
CPU |
厨房(资源) |
|
PCB |
厨师笔记(记录进度) |
|
时间片 |
厨师轮班时间 |
|
阻塞 |
等锅开、等客人 |
|
挂起 |
厨师下班回家(状态存在但不占厨房) |
|
上下文切换 |
厨师交接笔记,换另一位上场 |
一句话记住:
进程是资源的容器,线程是执行的手。
CPU 不断切换厨师,让所有菜都能被端上桌,这就是现代操作系统的核心智慧。
4632

被折叠的 条评论
为什么被折叠?



