进程的概念和特征
这一节要解决的问题只有一个:为什么把程序跑起来这件事,需要发明”进程”这个新概念?
答案不在”进程是程序的一次执行”这句定义里,而在它前面的那段历史——是并发逼出来的。理解了这个因果,后面的四个特征、状态转换、PCB 全都是顺推出来的结论,不需要背。
机制
单道程序时代:程序自己就够了
在单道批处理系统里,内存中始终只有一道程序。它从头跑到尾,独占 CPU、独占内存、独占所有设备,中间没有任何人打扰它。
这种环境有一个非常好的性质:封闭性。程序的执行结果只由它的初始条件决定。今天用这组输入运行,明天用同样的输入再运行,无论中间相隔多久、机器是否繁忙,结果都完全一致。由封闭性又直接得到可再现性。
在这种世界里,“程序”这一个概念就足够描述一切了。想知道机器在干什么,看那段代码跑到第几行就行。
多道程序一引入,程序这个概念就不够用了
为了让 CPU 在某道程序等 I/O 时别闲着,系统开始在内存里同时放多道程序,谁等 I/O 就切到别人。这一步是所有复杂性的源头。
第一个坏消息是**异步性**:每道程序都以不可预知的速度向前推进。它什么时候被切走、切走多久、等的资源什么时候到位,全都不确定。这不是故障,是多道环境下必然且正常的现象。
第二个坏消息是异步性的后果:封闭性没了。当两道程序共享同一个变量时,最终结果取决于它们交替执行的先后次序,而次序是不确定的。于是同样的输入可能得出不同的结果,可再现性跟着一起丢掉。
疑问点:如何准确表述"并发进程失去封闭性"
- 并发进程失去封闭性,是指()。 A.多个相对独立的进程以各自的速度向前推进 B.并发进程的执行结果与速度无关 C.并发进程执行时,在不同时刻发生的错误 D 并发进程共享变量,其执行结果与速度有关
这道题的答案是 D,而不是看起来也很像的 A。区分点在于:A 描述的是异步性本身,D 描述的才是”失去封闭性”这个后果。异步性是原因,失去封闭性是结果,题目问的是结果。而且 D 里那个”共享变量”是关键限定——两个进程如果井水不犯河水,各跑各的,速度再不确定也不会互相影响结果。必须有共享,速度的不确定才会传导成结果的不确定。
顺带把 B 也划掉:B 说”结果与速度无关”,那正是保持封闭性的描述,意思刚好反了。
第三个坏消息:程序和”这一次执行”不再一一对应
单道时代,一段代码就对应一次运行,两者可以混为一谈。多道环境下这个对应关系彻底断了:
- 同一个程序可以被同时运行多次。同时开启两个
bash,二者运行的是磁盘上同一份可执行文件,却是两个独立的执行流,各有各的当前目录、变量取值和执行位置。 - 反过来,一个执行流也可以在生命周期中途换掉自己的程序。Linux 里
fork之后调用exec,代码段被整个替换成新程序,但它仍然是原来那个执行实体(PID 都不变)。
所以”程序”这个静态概念无法回答一个最基本的问题:系统现在到底有几个”正在进行的活动”,各自进行到哪一步了?
于是有了进程
系统需要一个能够描述**“一次具体的、动态的执行过程”**的东西(→ 进程),并且要能把这个过程的全部状态记下来,这样才能在切走之后还原回去。这就是进程:
进程是程序在某个数据集合上的一次运行过程,是系统进行资源分配和调度的独立单位。
定义里有三个词都是有分量的,一个都不能省:
“一次” ——强调这是一个具体的实例,而非代码本身。开启两个 bash 即两次运行、两个进程。
“某个数据集合” ——同一段代码配不同的数据,是不同的进程。这解释了为什么进程必须包含数据段,而不能只有代码。
“资源分配和调度的独立单位” ——这句话点明了进程被发明出来的用途:OS 需要一个记账单位。分内存分给谁?调度调的是谁?回答都是进程。(引入线程之后这句话会被拆成两半,调度单位让给线程,资源分配单位仍留在进程,见 2.1.6。)
进程实体:把这个动态过程”落到实处”
进程是个过程,过程是摸不着的。系统要管理它,必须有一份看得见的东西,这就是**进程实体**(进程映像):
进程实体 = 程序段 + 相关数据段 + PCB
- 程序段:要执行的代码。
- 数据段:这次运行用到的原始数据和中间结果——这是”某个数据集合”的落地。
- PCB:进程标识、当前状态、调度信息、资源清单、现场信息。
三者当中,PCB 是进程存在的唯一标志。创建进程的实质就是创建 PCB,撤销进程的实质就是回收 PCB。程序段可以和别的进程共享(两个 bash 共用一份代码),数据段可以为空,唯独 PCB 一个进程一份、不可或缺——要判断系统里有没有这个进程,就看有没有它的 PCB。
注意”进程”和”进程实体”是两个层次的词:进程强调动态的过程,进程实体强调按下暂停键之后内存里的那份快照。教材说”进程是进程实体的运行过程”,就是在说这层关系。
边界
并发 ≠ 并行
这是全章最基础的一对,也是最容易在选择题里栽跟头的地方。
关键结论:单核 CPU 上可以并发,但不能并行。 并行是并发的一个特例,不是同义词。题目里出现”单处理机""同一时刻”这类字眼时要格外警惕。
特征之间不是并列的,是有依赖的
教材把并发、共享、虚拟、异步四个特征平铺着列出来,容易让人误以为它们地位相同。实际上:
并发和共享是最基本的两个特征,虚拟和异步建立在并发之上。
因果链是这样的:因为要提高资源利用率,所以引入并发;有了并发,多个进程就要共享资源;为了让每个进程感觉自己独占资源,才需要虚拟;而并发带来的推进速度不确定,就是异步。
所以如果一道题问”取消并发之后还剩什么特征”,答案是虚拟和异步都会跟着消失。
相对速度由谁决定
疑问点:并发进程的相对速度由什么决定
- 并发进程执行的相对速度是()。 A.由进程的程序结构决定的 B.由进程自己来控制的 C.与进程调度策略有关 D.在进程被创建时确定的
其中”程序结构”一项的确切含义需一并厘清。
答案是 C。
这道题把”异步性由谁造成”问得很直白。逐项分析:
- A 程序结构指的是代码本身的组织方式——有几个循环、几层分支、调用了哪些函数。它决定了这个进程总共要执行多少条指令,但决定不了这些指令什么时候被 CPU 执行。
- B 由进程自己控制是错的,而且错得最有教育意义:进程恰恰无法控制自己什么时候被切走。 时间片到了就被抢占,这是 OS 的决定,进程没有发言权。这正是异步性的本质。
- D 创建时确定也是错的。创建时确定的是优先级等初值,但实际推进速度还要看运行期间就绪队列里有谁、系统忙不忙。
- C 调度策略才是对的。谁先跑、跑多久、什么时候被换下来,全是调度算法说了算。
一句话记法:进程的相对速度不掌握在进程手里,掌握在调度器手里。
对照速查
| 程序 | 进程 | |
|---|---|---|
| 静/动 | 静态 | 动态 |
| 存在位置 | 外存(文件) | 内存(有 PCB) |
| 生命期 | 长期存在 | 有创建有消亡,暂时的 |
| 对应关系 | 一个程序可对应多个进程 | 一个进程可先后执行多个程序 |
| 组成 | 代码 + 数据 | 程序段 + 数据段 + PCB |
| 是否拥有资源 | 否 | 是(资源分配的独立单位) |
| 特征 | 含义 | 常考边界 |
|---|---|---|
| 并发 | 同一时间段内多个进程都在推进 | 单核可并发,不可并行 |
| 共享 | 资源被多进程共同使用 | 分互斥共享(如打印机)和同时共享(如磁盘) |
| 虚拟 | 一个物理实体变多个逻辑实体 | 虚拟处理机、虚拟内存、虚拟设备 |
| 异步 | 推进速度不可预知 | 由调度策略决定,进程自己控制不了 |
考点
- 程序与进程的区别(几乎年年以选择题形式出现)
- 并发 vs 并行的判据是”时间段”还是”时刻”
- 失去封闭性的准确表述:共享变量 + 结果与速度有关
- PCB 是进程存在的唯一标志
- 四个特征的依赖关系:并发和共享最基本
链接
- 🏠 返回总览:操作系统第 2 章:进程与线程总览
- ➡️ 下一节:2.1.2 进程的组成
- 📖 名词库:第 2 章名词库