Appearance
进程基本概念
2026 大纲 二(一)1 进程与线程的基本概念。
一个 CPU,很多程序,得先有个东西来指代"跑着的那一个"
操作系统概述那一章立了个总链:一台机器要服侍很多程序。 内存那边靠"同时装进去"解决,CPU 这边只能靠轮流——一毫秒给你、下一毫秒给他。
可"轮流"这两个字一落地就出问题:切走的时候,得把什么东西存起来? 切回来的时候,怎么恢复到刚才那一刻?
要回答这两个问题,就必须先有一个东西来指代"正在跑的那一份"。 它不能是程序本身——程序是躺在磁盘上的一段代码,静态的、可以被同时跑好几份; 需要的是"这一次执行"这个动态对象,它有自己的当前指令位置、自己的寄存器值、 自己的一片内存。这个对象就是进程。
再往下推一层就得到了本章的骨架。并发意味着一个程序执行时可能被打断、 被别的程序插进来改掉共享的东西,于是它失去了封闭性;失去封闭性就 失去了可再现性(同样的输入可能算出不同结果)。要把这条底线守回来, OS 必须能描述每次执行的状态、能控制它——于是有了 PCB。
整章就是被这条链推着走的:
一个 CPU 要被很多程序用 ⇒ 得有"运行中的程序"这个对象(进程,以及后来把 "资源拥有者"和"调度对象"拆开得到的线程)⇒ 得有切换它的机制和"下一个选谁"的规则 (上下文切换与调度)⇒ 可它们一旦能交替执行,就会在共享的东西上互相踩 (同步与互斥)⇒ 而互相等着对方手里的东西,就会谁也动不了(死锁)。
每一步都是上一步带出来的新问题。 这一节先把最底下那个对象讲清楚—— 进程是什么、PCB 里装什么、以及为什么后来还要再拆出线程。
一、进程是被并发逼出来的
这条链要一步步走:
- 单道程序时代内存里只有一个程序,独占全部资源从头跑到尾,执行具有封闭性(结果只由自身决定)与可再现性(同样输入必得同样输出)。
- 多道程序后,任一程序运行时的环境都会被别的程序改动,封闭性丢失。
- 封闭性一丢,可再现性也跟着丢。程序 A 反复做
N = N + 1,程序 B 反复做"打印 N,然后置 N = 0";同一个初始值, N = N + 1插在 B 的两条语句之前、之间、之后,得到三组完全不同的结果。 - 于是必须承认:"程序"这个静态概念已不足以描述正在发生的事情。同一份代码跑两次是两回事;跑到一半被打断,恢复时得知道从哪继续。
- 要能描述、能控制,就得给每一次执行配一个数据结构,记录它是谁、跑到哪了、占了什么——这就是 PCB。
- 程序段 + 数据段 + PCB 合起来,才是能独立参与并发的实体,即进程实体(进程映像)。
二、进程映像的三块分处两个空间
三、PCB 的四类信息,是从"OS 要拿它干四件事"推出来的
| OS 要做的事 | 因此 PCB 里必须有 | 具体内容 |
|---|---|---|
| ① 在成百上千个进程里认出它,还要知道谁是它爹 | 进程标识符信息 | 内部标识符(数字型进程号)、外部标识符(用户可读的名字)、父进程标识、子进程标识、用户标识 |
| ② 让它能停下再接着跑(间断性运行) | 处理机状态信息(即上下文) | 通用寄存器、指令计数器 PC、程序状态字 PSW、用户栈指针 |
| ③ 决定下一个轮到谁上 CPU | 进程调度信息 | 进程状态、优先级、已等待时间、已执行时间、阻塞原因(所等事件) |
| ④ 找到它的程序、数据和资源,并让它能与别人同步通信 | 进程控制信息 | 程序和数据的内存/外存首址、同步与通信机制(信号量、消息队列指针)、资源清单、链接指针 |
认出它、恢复它、调度它、管理它的资源——操作系统对进程再没有第五种动作。上下文切换的细节见 上下文切换机制。
孙钟秀《操作系统教程》的两处口径差异,与判断题里怎么答(两本书对不上时展开)
进程映像的划分:汤小丹《计算机操作系统》讲的是 PCB + 程序段 + 数据段三块。孙钟秀把进程映像拆成 PCB + 进程数据块 + 进程核心栈(程序块另计),多出来的核心栈是每个进程在内核态工作时用的栈,用于保存中断/异常现场与内核函数调用的参数、局部变量、返回地址。
两个口径不矛盾:核心栈本来就是进程私有的、位于内核空间的一块,汤书把它并进了"进程实体"未单列。判断题里出现"进程在内核态执行时使用的栈属于该进程"时,按孙书口径是明确成立的。
PCB 信息的分类:孙书分为标识信息、现场信息、控制信息三类——差别只在于它把上表的③④合并进了"控制信息"。两种分法的字段集合是一样的,四类分法只是把"给调度程序看的"单独摘了出来。
四、四个特征是一条链,不是并列的四个词条
| 序 | 特征 | 从哪一步推出来 | 与程序的对比 |
|---|---|---|---|
| 1 | 动态性 | 进程的实质是进程实体的执行过程——由创建而产生、由调度而执行、由撤销而消亡,有生命期 | 程序只是一组有序指令的集合,存放在介质上,是静态的 |
| 2 | 并发性 | 既然是"执行过程",多个进程实体就可以同存于内存、在一段时间内同时运行 | 没建立 PCB 的程序不能参与并发执行 |
| 3 | 独立性 | 要能并发,每个进程实体就必须能独立运行、独立获得资源、独立接受调度 | 未建立 PCB 的程序不能作为独立单位参与运行 |
| 4 | 异步性 | 各进程独立推进,速度不可预知——这正是并发执行会丢失可再现性的根源 | — |
后三条都能从动态性推出来(有生命期 ⇒ 可以有多个同时存在 ⇒ 各自要独立 ⇒ 各自速度不可控),反过来推不回去。
五、进程与程序的关系
| 比较维度 | 进程 | 程序 |
|---|---|---|
| 状态 | 动态,有生命周期 | 静态,永久存储 |
| 存在标志 | PCB | 磁盘上的可执行文件 |
| 资源 | 拥有资源(内存、文件等) | 不涉及资源分配 |
| 并发 | 可以并发执行 | 本身不能并发 |
| 创建/撤销 | 可以被创建和撤销 | 无此概念 |
| 数量关系 | 一个程序可对应多个进程 | 一个进程也可包含多个程序 |
"一个进程包含多个程序"的来源:除主程序外,运行时装入的动态链接库也是独立的程序,被映射进同一地址空间供本进程调用(见 程序的链接与装入);一个进程也可以先后调用不同的程序完成不同阶段的工作。
六、线程的基本概念
拆开进程的两个身份:进程继续做资源分配的基本单位(地址空间、打开的文件、I/O 设备仍归它),线程接过 CPU 调度的基本单位(只是进程内的一条执行流)。于是同一进程内可有多条执行流共用一套资源,创建与切换只需处理执行流本身。
私有还是共享,判据只有一条:切换执行流时必须换掉的 ⇒ 线程私有;不必换的 ⇒ 进程内共享。按这条一推即得:
| 内容 | 为什么归这边 | |
|---|---|---|
| 线程私有 | 线程 ID、程序计数器 PC、寄存器集合、栈(用户栈 + 内核栈)、线程控制块 TCB | 换一条执行流就得换一套"跑到哪了"的现场;栈里存的是本条执行流的函数调用链和局部变量,不可能共用 |
| 进程内共享 | 代码段、全局/静态数据区、堆、打开的文件、信号处理方式、地址空间与页表 | 换执行流不需要换地址空间——这正是线程切换比进程切换便宜的根本原因 |
堆和栈落在两边,是最容易搞反的一处:堆是进程级的共享资源(一个线程 malloc 出来的地址,另一个线程可以直接访问),栈是线程私有的(每条执行流的调用链必须各走各的)。
| 比较维度 | 进程 | 线程 |
|---|---|---|
| 是什么 | 资源分配的基本单位 | CPU 调度的基本单位 |
| 拥有的资源 | 地址空间、文件、设备等全套 | 只有 TCB、PC、寄存器、栈这点"必不可少的" |
| 创建/撤销开销 | 大:要分配和回收全套资源 | 小:只建一个 TCB 加一小块栈空间 |
| 切换开销 | 大:要换地址空间 | 小:地址空间不变 |
| 通信方式 | 需要 进程间通信 机制 | 直接读写共享的全局变量与堆 |
| 独立性 | 强:地址空间互不可见 | 弱:一个线程的栈都能被同进程其他线程读写 |
| 出错影响 | 一个进程崩溃不影响别的进程 | 一个线程越界写坏共享数据,全进程受害 |
线程在其余三条上的落点:状态与转换(含"线程阻塞会不会拖垮进程")见 进程状态与转换;TCB 的内容与线程的创建、终止见 进程的组织与控制;内核级与用户级两种实现方式见 线程。
考点速记
- 进程是被并发逼出来的:并发 ⇒ 失去封闭性 ⇒ 失去可再现性 ⇒ 必须给每次执行配一个可描述、可控制的结构,即 PCB。程序段 + 数据段 + PCB 构成进程实体。
- 创建/撤销进程实质就是创建/撤销 PCB,PCB 是进程存在的唯一标志。⚠️ 但"唯一标志"不等于"PCB 就是进程"。
- PCB 的四类信息对应 OS 要做的四件事:进程标识(认出它)、处理机状态(切走再切回)、进程调度(决定给不给 CPU)、进程控制与资源(管它的家当)。⚠️只有处理机状态信息(上下文)是切换时必须保存恢复的。
- PCB 位于内核空间,进程自己改不了——这是内存保护的前提。
- ⚠️不管系统是否支持线程,进程都是资源分配的基本单位。 引入线程后被分走的是调度这个身份,资源分配的身份始终留在进程这一侧。
- 线程是把"资源拥有者"与"调度对象"两个身份拆开的产物:进程仍是资源分配单位,线程成为调度(CPU 分配)单位。
- 私有 / 共享的唯一判据是"切换执行流时要不要换掉它":栈私有(每条执行流有自己的调用链)、寄存器与 PC 私有;堆、数据段、代码段、打开的文件共享(它们属于进程这个资源容器)。
- ⚠️同一进程内各线程共享同一个地址空间,不是"各自不同的地址空间"。
- ⚠️父子进程不共享虚拟地址空间:
fork之后子进程得到的是父进程地址空间的副本(现代系统用写时复制实现),两者各有各的 PCB、可以并发执行、也仍然要为临界资源互斥。
这一节在真题里被考过的形式:
process-thread-concepts 这个标签下挂了 19 道题,横跨进程创建与终止、线程共享、 进程状态、死锁、调度时机、内存布局——本页下方练习区渲染的题远比本节内容宽,属正常。 真正落在本节的有三道,都在考"进程 / 线程 / 父子进程各自拥有什么"这一组边界:
- 判断进程与线程的四条叙述(2012-31)。答不管系统是否支持线程,进程都是资源分配的基本单位。⚠️ 另三项各错一处:"线程是资源分配单位、进程是调度单位"把两个身份对调了(速记第五、六条);"系统级线程和用户级线程的切换都需要内核支持"错——用户级线程的切换在用户态完成,内核根本不知道(详见线程);"同一进程中各线程拥有各自不同的地址空间"错——它们共享同一个地址空间(速记第八条)。
- 判断父进程与子进程的四条叙述,选错误的(2020-29)。错项是"父进程与子进程共享虚拟地址空间"。⚠️ 子进程拿到的是副本不是共享——这正是它与"线程"的分界:线程共享地址空间,子进程复制地址空间。另三条都对:可以并发执行、有不同的 PCB、不能同时使用同一临界资源。
- 给虚拟地址空间布局图与一段 C 程序,问各对象位于哪个区域(2025-46,大题)。PCB 在操作系统内核区是本节的结论;其余分问(
main在代码段、全局指针在数据段、局部变量在栈、malloc的空间在堆)在运行时内存映像与地址空间详述。
复习优先级:必须拿满,且判据只有两组。 一组是"资源分配归进程、调度归线程" (第五、六条),另一组是"线程共享地址空间、子进程复制地址空间"(第八、九条)。 把这四条钉死,三道题都是送分。第三条 PCB 的四类信息要能说出各自对应 OS 的哪件事, 但很少单独设问。
易错:认为引入线程后进程就不再是资源分配单位。被分走的只有"调度"这个身份,资源分配始终在进程一侧。
易错:把进程与线程的两个身份对调。进程是资源分配单位,线程是调度单位。
易错:认为同一进程内的各线程有各自不同的地址空间。共享同一个——这正是线程轻量的原因。
易错:认为父子进程共享虚拟地址空间。子进程拿到的是副本;共享地址空间的是线程。
易错:认为 PCB 就是进程。PCB 是进程存在的唯一标志,进程实体是程序段 + 数据段 + PCB。
易错:认为 PCB 里的信息切换时都要保存恢复。只有处理机状态信息(上下文)要。
易错:认为进程可以修改自己的 PCB。PCB 在内核空间,进程碰不到。
教材出处
- 汤小丹《计算机操作系统》2.2.1 进程的定义和特征,印刷 p35–p36:进程实体(又称进程映像)由程序段、相关的数据段和 PCB 三部分构成;进程的四个特征(动态性、并发性、独立性、异步性)
- 汤小丹《计算机操作系统》2.2.4 进程管理中的数据结构,印刷 p40–p41:PCB 的五项作用与四类信息(进程标识符、处理机状态、进程调度信息、进程控制信息)
- 汤小丹《计算机操作系统》2.7.2、2.7.3,印刷 p77:线程仅拥有 TCB、程序计数器、一组寄存器和堆栈,其余资源与同进程的其他线程共享
- 孙钟秀、费翔林《操作系统教程》(第 6 版)2.3.2,印刷 p56–p57:PCB 的三类信息(标识信息、现场信息、控制信息);进程映像 = 进程控制块 + 进程数据块 + 进程核心栈
相关知识
操作系统的基本概念|运行时内存映像与地址空间|进程状态与转换|进程的组织与控制|线程