二、进程与线程管理(第11-28题)
第11题
进程是程序在一个数据集合上的一次运行过程,是系统进行资源分配和调度的基本单位。进程具有动态性、并发性、独立性、异步性和结构性等特征,其中最基本、最本质的特征是( )。 A. 并发性 B. 独立性 C. 动态性 D. 结构性
答案:C
考点定位:二、进程与线程管理——进程的定义与最基本特征,难度★☆☆☆☆,是国企笔试和互联网笔试操作系统部分的入门级送分题,出现频率极高。
【结论】 进程最基本、最本质的特征是动态性,选 C。进程区别于静态程序的核心就在于它具有创建、运行、消亡的完整生命周期。
【逐项辨析】
- A 错误——并发性描述多个进程在同一时间间隔内交替执行的能力,它建立在动态性基础之上,并非进程自身的最本质属性。
- B 错误——独立性说明进程可以独立申请资源和被调度,是进程在系统中的“地位”属性,不是最基本特征。
- C 正确——进程是程序的一次执行过程,由创建而产生、由调度而执行、由撤销而消亡,具有明显的生命周期,动态性是其他一切特征的前提。
- D 错误——结构性说明进程由程序段、数据段和 PCB 三部分组成,属于组成形式上的特征,而非最本质特征。
【知识点】 进程的五大特征及其关系:
| 特征 | 定义 | 与其他特征的关系 |
|---|---|---|
| 动态性 | 进程是程序的一次执行过程,有生命周期 | 最基本特征,其他特征的前提 |
| 并发性 | 多个进程在一段时间内同时存在、交替运行 | 建立在动态性之上 |
| 独立性 | 能独立运行、独立获得资源、独立接受调度 | 进程作为基本单位的体现 |
| 异步性 | 各进程按各自不可预知的速度向前推进 | 并发执行的必然结果 |
| 结构性 | 由程序段、数据段、PCB 组成 | 动态性的组织载体 |
进程与程序的根本区别在于:程序是静态的指令集合,可以长期保存在外存;进程是动态的执行过程,是暂时的、有生命的。所有其他特征(并发性、独立性等)都以“进程是动态的活动”为前提,因此动态性位居首位。
【记忆锚点】 口诀——“动静对比记心头,动态本是第一流”。另可用一句话概括:程序是菜谱,进程是炒菜——菜谱可以一直放在那里(静态),炒菜必须有开始和结束(动态)。
【易混对比】
| 对比项 | 进程 | 程序 |
|---|---|---|
| 本质 | 动态的执行过程 | 静态的指令集合 |
| 存在周期 | 临时,运行结束即撤销 | 长期,可永久保存 |
| 组成 | 程序段+数据段+PCB | 仅指令与数据 |
| 数量关系 | 一个程序可对应多个进程 | 一个进程也可执行多个程序 |
换个问法:“进程与程序的本质区别是什么?”——答案仍是“动态 vs 静态”,但可能以填空或简答形式出现。与第 12 题连考。
【自测】 下列关于进程特征的描述中,正确的是哪一项? A. 进程是静态的指令集合 B. 并发性是进程最基本、最本质的特征 C. 进程具有动态性、并发性、独立性、异步性和结构性 D. 结构性是进程区别于程序的最核心特征
答:C。进程五特征中动态性最本质;A/D 把程序与进程属性说反,B 把「OS 核心概念」误当成「进程自身最本质特征」。 〈出处:同型题〉
【易错提醒】 ①不要因为“并发”是操作系统的核心概念就误选并发性,题目问的是“进程这一实体自身”的最基本特征。②程序是静态的,进程是动态的,凡出现“进程是静态的”“程序是动态的”之类表述必错。③记忆口诀:进程五特征中“动态”打头,是最本质的一条。
【知识关联】 本题考点:进程的特征——动态性是进程最基本、最本质的特征。同库题群:第1题(OS 四个基本特征中最基本的是“并发”,与本题“进程自身的特征”不可混)、第12题(进程 vs 程序)、第13题(PCB 是进程存在的唯一标志)、第28题(进程组成);补题相关:补-01(生命周期终点与 PCB 回收)。面试:为什么说进程是动态的?
【拓展延伸】 变式:把「最基本、最本质的特征」换成「程序与进程的根本区别」,题眼同样落在动态性(进程有生灭,程序是静态代码)。(本题答案 C,以题干选项为准)
第12题
关于进程与程序的关系,下列说法中正确揭示了二者本质区别的是( )。 A. 程序是动态的,而进程是静态的 B. 一个程序只能对应一个进程,一个进程也只能对应一个程序 C. 进程是程序的一次执行过程,是动态的;而程序是一组有序指令的集合,是静态的 D. 程序存放在内存中,进程存放在磁盘上
答案:C
考点定位:二、进程与线程管理——进程与程序的本质区别,难度★☆☆☆☆,属于国企笔试操作系统概念题中的高频送分点。
【结论】 进程是程序的一次执行过程,是动态的;程序是一组有序指令的集合,是静态的,选 C。二者本质区别就在于“动态执行过程”与“静态指令集合”的对立。
【逐项辨析】
- A 错误——把动静属性完全说反了,程序是静态的,进程是动态的。
- B 错误——程序与进程是多对多关系,同一程序可对应多个进程(如多次打开浏览器),一个进程也可执行多个程序(如 shell 调用不同命令)。
- C 正确——准确指出进程是程序的一次执行过程、具有动态性,而程序是指令集合、是静态的,这正是二者的本质区别。
- D 错误——程序通常存放在外存(磁盘)上,进程运行期间的程序段和数据段位于内存中,存放位置说反了。
【知识点】 进程与程序的全面对比:
| 对比维度 | 程序 | 进程 |
|---|---|---|
| 本质定义 | 一组有序指令的集合 | 程序在数据集合上的一次执行过程 |
| 静态/动态 | 静态,可长期保存 | 动态,有生命周期 |
| 存储位置 | 外存(磁盘等) | 内存(运行时) |
| 组成内容 | 指令+数据 | 程序段+数据段+PCB |
| 数量关系 | 一个程序可产生多个进程 | 一个进程可运行多个程序 |
| 并发性 | 本身不能并发执行 | 可以并发执行 |
程序是被动的实体,本身不消耗资源,只是被读取和执行的文本;进程是主动的实体,占用 CPU、内存、I/O 等资源,与操作系统主动交互。引入进程的目的正是为了让操作系统能够管理和调度这些动态的执行实体。
【记忆锚点】 类比——“程序是乐谱,进程是演奏”。同一份乐谱可以被不同乐队多次演奏(一个程序多个进程),一次演奏中也可以演奏多首乐曲(一个进程多个程序)。乐谱放在书架上不会动(静态),演奏必须有开始和结束(动态)。
【易混对比】
| 易混概念 | 正解 | 常见错法 |
|---|---|---|
| 动静属性 | 程序静态,进程动态 | 说反或说程序也动态 |
| 数量关系 | 多对多 | 误认为一对一 |
| 存储位置 | 程序在外存,进程在内存 | 说反 |
| 是否含 PCB | 进程有 PCB,程序没有 | 忽略 PCB 的存在 |
换个问法:“一个 C 语言源程序经编译链接后形成可执行文件,运行该文件时系统创建了几个进程?”——运行一次创建一个进程,运行 N 次创建 N 个进程。与第 11 题连考。
【自测】 关于进程与程序的关系,下列说法错误的是: A. 同一程序被多次执行会产生多个不同的进程 B. 进程是程序的一次执行过程,具有动态性 C. 程序存放在内存中,进程存放在磁盘上 D. 进程除了程序段和数据段外,还包含进程控制块 PCB
答:C。自测问错误项:C 把存放位置说反了——程序通常在外存(磁盘),运行期的进程映像才在内存;A/B/D 对进程与程序关系的表述正确。 〈出处:同型题〉
【易错提醒】 ①“一个程序对应一个进程”是典型错误说法,反复被用作干扰项。②进程与程序的区别还要抓住 PCB:进程有 PCB,程序没有。③程序可以长期存在,进程是临时存在的,运行结束即被撤销。
【知识关联】 本题考点:进程 vs 程序——动态执行过程 vs 静态指令集合,二者多对多。同库题群:第13题(PCB 唯一标志)、第28题(进程三部分组成);补题相关:补-01(生命周期终点与 PCB 回收)。面试:从可执行文件到运行中进程,内核做了什么(装载、建 PCB、分配资源)?
【拓展延伸】 变式:同一程序运行 3 次对应几个进程/几个 PCB(3);存放位置(程序多在外存,进程映像在内存)。Linux:execve 装载新映像,ps 可见多实例。(本题答案 C,以题干选项为准)
第13题
在操作系统中,进程存在的唯一标志是( )。 A. 进程所对应的程序代码 B. 进程控制块 PCB C. 进程所占用的内存空间 D. 进程所分配到的设备资源
答案:B
考点定位:二、进程与线程管理——PCB 的作用与内容,难度★☆☆☆☆,是国企笔试和互联网笔试中反复考查的基础概念题。
【结论】 进程存在的唯一标志是进程控制块 PCB,选 B。操作系统通过 PCB 感知进程的存在并实施管理。
【逐项辨析】
- A 错误——程序代码是进程运行的依据,但同一段程序代码可被多个进程共享使用,它不能唯一标识一个进程。
- B 正确——PCB 记录了进程的全部控制信息,系统靠它管理进程,进程与 PCB 一一对应,是进程存在的唯一标志。
- C 错误——内存空间是进程运行所需的资源,不同进程可以共享同一内存区域(如共享库),它无法唯一标识进程。
- D 错误——设备资源只是进程可能占用的资源之一,很多进程根本不占用设备,不能作为存在标志。
【知识点】 PCB 是操作系统为每个进程建立的数据结构,包含以下主要内容:
| 信息类别 | 具体内容 | 作用 |
|---|---|---|
| 进程标识信息 | PID、父进程 ID、用户 ID | 唯一标识进程身份 |
| 处理机状态信息 | 程序计数器 PC、状态字 PSW、通用寄存器 | 进程切换时保存/恢复现场 |
| 进程控制信息 | 进程状态、优先级、调度信息 | 供调度算法决策使用 |
| 资源分配信息 | 内存指针、打开文件表、I/O 设备清单 | 记录进程占用的全部资源 |
| 链接信息 | 就绪队列指针、阻塞队列指针 | 将 PCB 组织成各种队列 |
操作系统把所有进程的 PCB 组织成线性表、链接表或索引表,如就绪队列、阻塞队列等。进程的创建本质就是创建 PCB并填入初始信息;进程的撤销本质就是回收 PCB及其关联资源。因此,没有 PCB,进程就不被操作系统承认。
【记忆锚点】 口诀——“PCB 是身份证,没它系统不认人”。类比:进程像是公司的员工,PCB 就是工牌——工牌上有姓名、部门、职位、当前状态(在岗/休假)等所有信息,公司只有通过工牌才能识别和管理员工。
【易混对比】
| 对比项 | PCB | TCB(线程控制块) |
|---|---|---|
| 对应实体 | 进程 | 线程 |
| 包含内容 | 地址空间、打开文件、资源清单等 | 线程 ID、PC、寄存器、栈指针 |
| 数量关系 | 一个进程一个 PCB | 一个线程一个 TCB,一个进程可含多个 TCB |
| 存在意义 | 进程存在的唯一标志 | 线程存在的标志 |
换个问法:“操作系统创建进程时首先做的工作是什么?”——分配空白 PCB 并填入初始信息。与第 19 题(PCB vs TCB)连考。
【自测】 下列关于 PCB 的说法中,错误的是: A. PCB 是进程存在的唯一标志 B. PCB 中保存了程序计数器和通用寄存器等处理机现场信息 C. 同一程序代码可以被多个进程共享,因此程序代码也能作为进程存在的唯一标志 D. 进程被撤销时,其 PCB 也随之被删除
答:C。同一程序代码可被多个进程共享,无法唯一标识进程;进程存在的唯一标志只能是 PCB。 〈出处:408 真题同型题〉
【易错提醒】 ①注意区分“进程存在的唯一标志是 PCB”与“进程是资源分配的基本单位”两个不同命题。②进程实体由程序段、数据段、PCB 三部分组成,其中只有 PCB 是操作系统专用的、与进程一一对应的。③创建进程的本质工作就是创建 PCB。
【知识关联】 本题考点:PCB 是进程存在的唯一标志。同库题群:第12题(进程 vs 程序)、第28题(进程组成与 PCB 内容)、第14–16题(状态与现场信息);补题相关:补-01(僵尸残留的正是 PCB)。面试:PCB 三大类信息分别是什么?创建/撤销进程的本质?
【拓展延伸】 变式:程序代码/内存/设备能否作为唯一标志(均不能,因可共享或可缺省)。Linux:task_struct 即 PCB;ps 与 /proc/<pid>/ 是其用户态投影。(本题答案 B,以题干选项为准)
第14题
在进程的三态模型中,下列状态转换中不可能发生的是( )。 A. 就绪态→执行态 B. 执行态→阻塞态 C. 就绪态→阻塞态 D. 阻塞态→就绪态
答案:C
考点定位:二、进程与线程管理——进程三态模型与非法转换,难度★★☆☆☆,是国企笔试与互联网笔试中出错率较高的高频考点。
【结论】 就绪态→阻塞态不可能发生,选 C。就绪态进程尚未占用 CPU,不可能主动发出等待请求。
【逐项辨析】
- A 错误(合法转换)——就绪进程被调度程序选中后获得 CPU,转为执行态。
- B 错误(合法转换)——执行中的进程因请求 I/O 或申请资源得不到满足,主动放弃 CPU 进入阻塞态。
- C 正确(不可能转换)——就绪态进程没有占用 CPU,不可能发出等待请求而直接进入阻塞态,只有执行态才能转为阻塞态。
- D 错误(合法转换)——阻塞进程所等待的事件发生后,它被唤醒转入就绪态排队。
【知识点】 进程三态模型的完整状态转换图与规则:
时间片用完 / 被抢占
+--------+ ----------------> +--------+
| 就绪态 | | 执行态 |
+--------+ <---------------- +--------+
^ 调度选中 |
| |
| 等待 I/O / 申请资源失败 |
+--------------------------------+
|
v
+--------+
| 阻塞态 |
+--------+
|
| I/O 完成 / 资源满足
v
(转就绪态)合法转换只有四条,触发条件如下:
| 转换方向 | 触发条件 | 是否合法 |
|---|---|---|
| 就绪态→执行态 | 进程被调度程序选中,获得 CPU | 合法 |
| 执行态→就绪态 | 时间片用完或被更高优先级进程抢占 | 合法 |
| 执行态→阻塞态 | 进程主动请求 I/O 或申请资源失败 | 合法 |
| 阻塞态→就绪态 | 等待的事件发生(I/O 完成等) | 合法 |
| 就绪态→阻塞态 | 就绪进程未占用 CPU,无法主动等待 | 非法 |
| 阻塞态→执行态 | 必须经过就绪态和调度,不能直达 | 非法 |
核心规则:只有执行态进程才能主动改变状态(转就绪或转阻塞);就绪态和阻塞态之间不存在直接转换。
【记忆锚点】 口诀——“就绪只能被调度走,阻塞只能被唤醒走,执行才能主动走”。也可以记为:“执行态是十字路口,就绪和阻塞是单行道”——执行态可以走向就绪或阻塞,但就绪只能走向执行,阻塞只能走向执行(经就绪中转)。
【易混对比】
| 转换 | 方向 | 本质原因 | 常见陷阱 |
|---|---|---|---|
| 时间片用完 | 执行→就绪 | 不缺资源,只缺 CPU | 误认为转阻塞 |
| I/O 请求 | 执行→阻塞 | 缺少资源,必须等待 | 误认为转就绪 |
| I/O 完成 | 阻塞→就绪 | 资源已到,等待 CPU | 误认为直接转执行 |
| 被抢占 | 执行→就绪 | 仍有资格运行 | 与“被阻塞”混淆 |
换个问法:“阻塞态进程可以直接转为执行态吗?”——不能,必须先经就绪态,再被调度选中。与第 15 题(执行→就绪的事件)和第 16 题(阻塞→就绪的触发)连考。
【自测】 在进程三态模型中,下列转换中必然经过调度程序的是: A. 执行态→阻塞态 B. 阻塞态→就绪态 C. 就绪态→执行态 D. 执行态→就绪态
答:C。就绪态→执行态只能由调度程序选中并分派,必然经过调度程序;执行态→阻塞态是运行进程自己执行等待原语(I/O 请求、P 操作)主动发起的,不经调度程序选路;阻塞态→就绪态由唤醒原语把进程放回就绪队列,也不是调度程序“选中”;执行态→就绪态是时间片到或被抢占的“换下”动作,被换下的进程并非由调度程序挑选运行。 〈出处:同型题〉
【易错提醒】 ①牢记“阻塞必须由执行态主动进入”,这是判断非法转换的关键。②阻塞→执行不是一步到位的,必须先转为就绪态再被调度。③只有执行态能转为就绪态或阻塞态,就绪态和阻塞态之间不存在直接转换。
【知识关联】 本题考点:进程三态模型与非法转换(就绪→阻塞不可能)。同库题群:第15题(执行→就绪的事件)、第16题(阻塞→就绪)、第29–38题(调度与状态变迁);补题相关:补-01(终止态与回收)。面试:为何只有执行态能主动进入阻塞?五态/七态如何补挂起?
【拓展延伸】 变式:判断给定转换序列是否合法;引入挂起后静止就绪/静止阻塞如何画。Linux:ps STAT 的 R/S/D 与就绪/可中断睡眠/不可中断睡眠对照。(本题答案 C,以题干选项为准)
第15题
下列事件中,会使进程从执行态转变为就绪态的是( )。 A. 进程的时间片用完 B. 进程等待的 I/O 操作已经完成 C. 进程申请内存空间失败而需要等待 D. 进程请求使用打印机,但打印机正被其他进程占用
答案:A
考点定位:二、进程与线程管理——导致执行态→就绪态的事件,难度★★☆☆☆,属于进程状态转换的高频辨析题,国企笔试尤为常见。
【结论】 进程的时间片用完会使进程从执行态转为就绪态,选 A。此时进程不缺资源,只是暂时失去 CPU。
【逐项辨析】
- A 正确——时间片用完属于剥夺式调度,进程未发生任何等待,只是暂时失去 CPU,因此由执行态转为就绪态。
- B 错误——等待的 I/O 完成是阻塞态转为就绪态的事件,是唤醒而非剥夺,与执行态无关。
- C 错误——申请内存失败说明进程缺少运行所需资源,只能转入阻塞态等待,而不是就绪态。
- D 错误——请求的打印机被占用,进程必须等待该资源,同样是由执行态转为阻塞态。
【知识点】 执行态转为就绪态与阻塞态的本质区别:
| 对比维度 | 执行态→就绪态 | 执行态→阻塞态 |
|---|---|---|
| 是否缺资源 | 不缺,仍具备运行条件 | 缺少某资源或等待某事件 |
| 是否仍想要 CPU | 是,排队等待再次获得 | 否,即使给 CPU 也无法运行 |
| 典型触发事件 | 时间片用完、被抢占 | 请求 I/O、申请资源失败 |
| 队列去向 | 就绪队列 | 阻塞队列(等待队列) |
| 再次运行条件 | 被调度程序选中 | 等待事件发生 + 被调度选中 |
判断执行态进程去向的唯一标准是“进程是否还缺资源”:不缺资源仅缺 CPU 则转就绪,缺少资源或必须等待事件则转阻塞。就绪态与阻塞态的根本差异也在于此:就绪态进程万事俱备只欠 CPU,阻塞态进程即使拿到 CPU 也无法继续。
【记忆锚点】 口诀——“不缺资源去就绪,缺资源才去阻塞”。另一个判断技巧:看该事件发生后进程能不能立即继续运行。时间片用完后,若立刻重新获得 CPU,进程可以无缝继续;I/O 未完成时,即使给 CPU,进程也因等数据而无法运行。
【易混对比】
| 事件 | 状态转换 | 原因 | 与第 14/16 题关联 |
|---|---|---|---|
| 时间片用完 | 执行→就绪 | 剥夺 CPU,不缺资源 | 第 14 题:合法转换 |
| I/O 请求发出 | 执行→阻塞 | 主动等待数据 | 第 14 题:合法转换 |
| I/O 操作完成 | 阻塞→就绪 | 数据已到,等 CPU | 第 16 题:唤醒机制 |
| 申请内存失败 | 执行→阻塞 | 缺少运行资源 | 同型考点 |
换个问法:“进程被更高优先级进程抢占后进入什么状态?”——就绪态,因为进程本身并不缺少任何资源。与第 14 题(三态转换合法性)和第 16 题(阻塞→就绪)连考。
【自测】 某进程正在 CPU 上运行,因请求访问磁盘而进入等待,该进程的状态变化是: A. 执行态→就绪态 B. 执行态→阻塞态 C. 就绪态→阻塞态 D. 阻塞态→就绪态
答:B。请求访问磁盘意味着等待 I/O 事件完成,进程缺的是事件而不是 CPU,故执行态→阻塞态;时间片到才是执行→就绪。 〈出处:同型题〉
【易错提醒】 ①判断标准是“进程是否还缺资源”:缺资源转阻塞,不缺资源仅缺 CPU 转就绪。②“时间片到”与“被抢占”都是执行→就绪,不要与“等待 I/O 完成”的阻塞→就绪混淆。③I/O 请求发出是执行→阻塞,I/O 完成是阻塞→就绪,方向恰好相反。
【知识关联】 本题考点:执行态→就绪态的触发事件(时间片用完/被抢占)。同库题群:第14题(三态与非法转换)、第16题(阻塞→就绪)、第29–38题(调度算法与剥夺)。面试:剥夺式与非剥夺式调度对响应时间的影响?
【拓展延伸】 变式:I/O 完成、申请打印机被占→阻塞相关,勿与时间片到混淆。工程:Linux CFS/实时调度均为可抢占;时间片/虚拟运行时间决定「失去 CPU 但仍就绪」。(本题答案 A,以题干选项为准)
第16题
某进程因等待 I/O 操作完成而进入阻塞态,当该 I/O 操作完成后,该进程将( )。 A. 立即由阻塞态转为执行态并继续运行 B. 由阻塞态转为就绪态,等待调度程序分配处理机 C. 继续保持阻塞态,直到其时间片用完 D. 由阻塞态转为挂起态,等待被换入内存
答案:B
考点定位:二、进程与线程管理——阻塞态转就绪态的触发条件,难度★☆☆☆☆,是进程状态转换中最常考的送分点之一。
【结论】 I/O 操作完成后,进程由阻塞态转为就绪态,等待调度程序分配处理机,选 B。
【逐项辨析】
- A 错误——唤醒只是让进程具备运行条件,处理机可能正被其他进程占用,不可能立即执行,必须先进入就绪队列。
- B 正确——I/O 完成是阻塞转就绪的典型触发事件,进程转入就绪态后等待调度。
- C 错误——阻塞态的进程不占用 CPU,不存在“时间片用完”的概念,而且事件已发生就必须唤醒。
- D 错误——挂起态是把进程换出到外存的状态,与 I/O 完成无关,属于对换技术的内容。
【知识点】 从 I/O 请求到进程重新运行的完整流程:
进程执行中
|
v
请求磁盘 I/O ---------------> 执行态→阻塞态
| |
v |
CPU 继续执行其他进程 |
| |
v |
磁盘控制器完成 I/O |
| |
v |
发出 I/O 中断 |
| |
v |
中断处理程序: |
1. 找到等待该 I/O 的进程 |
2. 将其 PCB 状态改为"就绪" |
3. 插入就绪队列 <------------------+
|
v
调度程序选中该进程
|
v
就绪态→执行态,继续运行阻塞态到执行态之间必须隔着就绪态和一次调度,原因有两点:一是 I/O 完成时 CPU 可能正在执行其他进程,不能强行中断;二是即使 CPU 空闲,也必须由调度程序统一决策,保证调度策略的一致性。
【记忆锚点】 口诀——“阻塞被唤醒,先到就绪再排队”。类比:阻塞态像是病人在检查室等报告,报告出来了(I/O 完成)不等于立刻看上医生,要先回到候诊室(就绪态)重新排队,等叫号系统(调度程序)叫到才能进诊室(执行态)。
【易混对比】
| 状态转换 | 触发者 | 中间状态 | 与第 14/15 题关联 |
|---|---|---|---|
| 执行→阻塞 | 进程主动请求 | 无 | 第 14 题:合法转换 |
| 执行→就绪 | 调度程序剥夺 | 无 | 第 15 题:时间片用完 |
| 阻塞→就绪 | 中断处理程序唤醒 | 无 | 本题:I/O 完成 |
| 就绪→执行 | 调度程序选中 | 无 | 第 14 题:合法转换 |
换个问法:“当 I/O 操作完成时,操作系统中断处理程序将阻塞进程放入哪个队列?”——就绪队列,而非直接投入运行。与第 14 题(三态转换)和第 15 题(执行→就绪)连考。
【自测】 进程因等待某事件而进入阻塞态,当该事件发生后,进程将: A. 立即获得 CPU 并继续运行 B. 由阻塞态直接转为执行态 C. 由阻塞态转为就绪态,等待调度 D. 继续保持阻塞态直到时间片用完
答:C。事件发生后进程被唤醒,从阻塞态转入就绪态排队;是否立刻占用 CPU 还要经调度,不能一步到执行态。 〈出处:同型题〉
【易错提醒】 ①“阻塞→就绪”由事件完成触发,而“就绪→执行”由调度触发,两者不能合并。②阻塞态进程不占用处理机,说它“时间片用完”逻辑上不成立。③注意挂起态(静止就绪/静止阻塞)与三态模型的区别,不要混为一谈。
【知识关联】 本题考点:I/O 完成后的状态转换(阻塞→就绪)。与第 14 题(三态模型中不可能发生的转换)、第 15 题(执行→就绪)构成状态机三角;与第 80 题在「I/O 完成由中断唤醒进程」上衔接;面试追问:为什么不能直接从阻塞进运行态?
【拓展延伸】 变式:从查询到 DMA 的演进逻辑。Linux 中断下半部/tasklet 是延伸。(本题答案 B,以题干选项为准)
第17题
关于进程与线程的区别,下列说法正确的是( )。 A. 线程是资源分配的基本单位,进程是处理机调度的基本单位 B. 同一进程内的各个线程各自拥有独立的地址空间 C. 线程的创建开销和切换开销都比进程更大 D. 进程是资源分配的基本单位,线程是处理机调度的基本单位
答案:D
考点定位:二、进程与线程管理——进程与线程的区别,难度★☆☆☆☆,是互联网笔试和国企笔试中考查频率最高的一道概念题。
【结论】 进程是资源分配的基本单位,线程是处理机调度的基本单位,选 D。
【逐项辨析】
- A 错误——把进程与线程的角色完全说反了,资源分配的单位是进程,调度的单位是线程。
- B 错误——同一进程内的线程共享所属进程的地址空间,只有进程之间才有独立的地址空间。
- C 错误——线程切换只需保存少量寄存器内容,不必切换页表和地址空间,开销比进程切换小得多。
- D 正确——准确表述了“进程是资源分配的基本单位,线程是处理机调度的基本单位”这一经典结论。
【知识点】 进程与线程的全面对比:
| 对比维度 | 进程 | 线程 |
|---|---|---|
| 基本定义 | 资源分配的基本单位 | 处理机调度的基本单位 |
| 地址空间 | 独立 | 同一进程内线程共享 |
| 拥有资源 | 拥有完整的资源集合 | 仅少量私有资源(TCB、栈、寄存器) |
| 切换开销 | 大(需切换页表、刷新 TLB、保存大量现场) | 小(只需保存/恢复少量寄存器) |
| 通信方式 | 需 IPC(管道、消息队列、共享内存等) | 直接读写共享数据,通信简单高效 |
| 创建开销 | 大(需分配资源、建立地址空间) | 小(只需分配栈和 TCB) |
| 崩溃影响 | 不影响其他进程 | 可能拖垮整个进程 |
引入线程的目的是减少并发执行的开销:传统进程既是资源分配单位又是调度单位,导致进程切换代价高昂。将调度属性剥离为线程后,同一进程内的线程切换不涉及地址空间变化,效率接近函数调用。现代操作系统(如 Linux)甚至将线程实现为“轻量级进程”(LWP),但概念上仍遵循上述分工。
【记忆锚点】 口诀——“进程管资源,线程抢 CPU”。另一口诀:“进程是房东,线程是租客”——房东(进程)拥有房子(资源)并交水电费(资源分配),租客(线程)只是住在里面并使用房子(被调度执行),同一房子内的租客共享客厅厨房(地址空间),但各自有独立卧室(私有栈)。
【易混对比】
| 易混点 | 正解 | 错解 | 与第 18/19 题关联 |
|---|---|---|---|
| 资源分配单位 | 进程 | 线程 | 第 19 题:线程共享进程资源 |
| 调度单位 | 线程 | 进程 | 第 18 题:内核级线程由内核调度 |
| 地址空间 | 进程间独立,线程间共享 | 线程也有独立地址空间 | 第 19 题:共享代码段和数据段 |
| 切换开销 | 进程 > 线程 | 线程 > 进程 | 第 18 题:用户级线程切换更快 |
换个问法:“同一个进程中的两个线程切换时,操作系统需要做哪些工作?”——只需保存/恢复线程的寄存器和栈指针,不需要切换页表或刷新 TLB。与第 18 题(用户级 vs 内核级线程)和第 19 题(线程共享资源)连考。
【自测】 在引入线程的操作系统中,下列说法正确的是: A. 线程是资源分配的基本单位,进程是 CPU 调度的基本单位 B. 同一进程内的线程拥有各自独立的地址空间 C. 进程切换的开销小于线程切换的开销 D. 进程拥有独立的地址空间,同一进程内的线程共享该地址空间
答:D。进程拥有独立地址空间、是资源分配基本单位;同一进程内线程共享该地址空间,线程才是 CPU 调度的基本单位,且切换开销更小。 〈出处:大厂面试高频〉
【易错提醒】 ①这组“谁是分配单位、谁是调度单位”的表述几乎年年出现,务必记牢。②线程共享进程的地址空间,所以一个线程崩溃可能影响同进程其他线程。③线程切换开销小是因为不涉及地址空间切换,不是因为它不保存现场。
【知识关联】 本题考点:线程与切换。与第 17–22、27 题;面试:线程模型?切换开销来自哪?
【拓展延伸】 变式:比较进程切换与线程切换。Go M:N、Linux NPTL 是工程对照。(本题答案 D,以题干选项为准)
第18题
关于用户级线程与内核级线程,下列说法正确的是( )。 A. 用户级线程的切换必须由操作系统内核参与完成 B. 用户级线程由用户程序库管理,内核不感知其存在;内核级线程由内核直接管理和调度 C. 一个用户级线程因系统调用而阻塞时,同一进程内的其他用户级线程仍可被内核调度执行 D. 内核级线程的创建和切换开销小于用户级线程
答案:B
考点定位:二、进程与线程管理——用户级线程与内核级线程的区别,难度★★☆☆☆,属于互联网笔试中区分度较高的考点。
【结论】 用户级线程由用户程序库管理,内核不感知其存在;内核级线程由内核直接管理和调度,选 B。
【逐项辨析】
- A 错误——用户级线程的切换完全在用户态由线程库完成,不需要内核参与,这正是它开销小的原因。
- B 正确——准确说明了两类线程的管理者与内核可见性差异,用户级线程内核不可见,内核级线程由内核直接管理调度。
- C 错误——用户级线程的阻塞会引起整个进程阻塞,内核只看到进程被阻塞,同进程内其他用户级线程同样无法运行。
- D 错误——内核级线程的创建与切换需要内核介入,开销大于用户级线程。
【知识点】 用户级线程(ULT)与内核级线程(KLT)的全面对比:
| 对比维度 | 用户级线程 ULT | 内核级线程 KLT |
|---|---|---|
| 管理者 | 用户空间线程库 | 操作系统内核 |
| 内核可见性 | 不可见,内核看到单线程进程 | 可见,内核独立调度每个线程 |
| 切换开销 | 小,用户态即可完成 | 大,需陷入内核 |
| 创建开销 | 小 | 大 |
| 阻塞影响 | 一线程阻塞,整个进程阻塞 | 一线程阻塞,不影响同进程其他线程 |
| 多核利用 | 无法真正并行,只能并发 | 可在多核上真正并行 |
| 典型实现 | POSIX pthreads(用户态实现) | Windows、Linux 原生线程 |
三种线程映射模型:
| 模型 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| 多对一 | 多个 ULT 映射到一个 KLT | 切换快 | 无法并行,一阻塞全阻塞 |
| 一对一 | 每个 ULT 对应一个 KLT | 可并行,阻塞隔离 | 创建开销大 |
| 多对多 | 多个 ULT 映射到多个 KLT | 兼顾两者优点 | 实现复杂 |
用户级线程的核心优势在于切换无需陷入内核,因此速度极快;核心劣势在于无法利用多处理机并行,且一个线程的阻塞会扩散到整个进程。内核级线程正好相反。
【记忆锚点】 口诀——“用户线程库管,内核线程核管;用户快但不并,内核慢但并行”。也可记为:“ULT 是地下党,内核不知道;KLT 是正规军,内核亲自管”。
【易混对比】
| 对比项 | 用户级线程 | 内核级线程 | 与第 17/19 题关联 |
|---|---|---|---|
| 谁调度 | 线程库 | 内核调度器 | 第 17 题:线程是调度单位 |
| 切换地点 | 用户态 | 内核态 | 第 19 题:线程私有栈 |
| 阻塞后果 | 全进程阻塞 | 仅该线程阻塞 | 第 17 题:进程是资源单位 |
| 并发 vs 并行 | 仅并发 | 可真正并行 | 同型考点 |
换个问法:“在采用多对一线程模型的系统中,若一个用户级线程执行阻塞式系统调用,会发生什么?”——整个进程都会被阻塞,因为内核只看到进程级别的阻塞。与第 17 题(进程 vs 线程)和第 19 题(线程资源)连考。
【自测】 关于用户级线程和内核级线程,下列说法错误的是: A. 用户级线程的切换不需要内核支持 B. 内核级线程可以在多处理器上并行执行 C. 一个用户级线程阻塞时,同进程的其他用户级线程仍可继续运行 D. 内核级线程的创建和切换开销大于用户级线程
答:C。C 为错误项:用户级线程由用户态库管理,内核只看到进程;一线程阻塞会使整个进程被内核置为阻塞,同进程其他用户级线程无法继续运行。 〈出处:同型题〉
【易错提醒】 ①核心区分点有三:谁管理、内核是否可见、一个线程阻塞是否影响全进程。②用户级线程“阻塞即全阻塞”是其最大缺点,常作为干扰项出现。③多对一模型无法利用多核,多对多模型兼顾两者优点,属于常考的延伸点。
【知识关联】 本题考点:线程与切换。与第 17–22、27 题;面试:线程模型?切换开销来自哪?
【拓展延伸】 变式:比较进程切换与线程切换。Go M:N、Linux NPTL 是工程对照。(本题答案 B,以题干选项为准)
第19题
在同一进程内,各线程之间( )。 A. 共享栈和寄存器,独享代码段和数据段 B. 既共享栈和寄存器,也共享代码段和数据段 C. 独享代码段和数据段,也独享栈和寄存器 D. 共享代码段、数据段和堆,独享栈、寄存器和线程控制块
答案:D
考点定位:二、进程与线程管理——线程共享与独占的资源,难度★★☆☆☆,是互联网笔试中反复出现的细节辨析题。
【结论】 同一进程内各线程共享代码段、数据段和堆,独享栈、寄存器和线程控制块,选 D。
【逐项辨析】
- A 错误——把共享与独享的对象颠倒了,栈和寄存器恰恰是线程私有的,而代码段和数据段是共享的。
- B 错误——栈和寄存器是线程执行现场的核心内容,各线程必须各自保存,不可能共享。
- C 错误——代码段和数据段属于进程级资源,由该进程所有线程共同使用,并非线程独享。
- D 正确——准确区分了共享的代码段、数据段、堆与独享的栈、寄存器、TCB。
【知识点】 同一进程内线程的资源共享与私有:
| 资源类型 | 具体内容 | 共享/私有 | 原因 |
|---|---|---|---|
| 代码段 | 程序指令 | 共享 | 所有线程执行同一份代码 |
| 数据段 | 全局变量、静态变量 | 共享 | 进程级数据,线程均可访问 |
| 堆 | 动态分配内存(malloc) | 共享 | 同一地址空间内分配 |
| 打开文件 | 文件描述符表 | 共享 | 进程级资源 |
| 信号处理 | 信号处理方式 | 共享 | 进程级设置 |
| 栈 | 局部变量、函数调用链 | 私有 | 各线程独立执行流 |
| 寄存器 | 通用寄存器组 | 私有 | 保存各自执行现场 |
| 程序计数器 | PC | 私有 | 记录各自执行位置 |
| TCB | 线程控制块 | 私有 | 线程存在的标志 |
判断依据:是否与执行现场绑定。代码、数据、堆等属于“房子里的家具”,所有住户(线程)共用;栈、寄存器、PC 属于“每个人的随身物品”,必须各自携带。线程切换时只需保存/恢复私有部分,共享部分保持不变。
【记忆锚点】 口诀——“代码数据堆共享,栈和寄存器各带;现场绑定皆私有,其余一律大家爱”。类比:进程是一个大办公室(地址空间),线程是办公室里的员工。办公室里的公共打印机、茶水间、文件柜(代码段、数据段、堆)大家共享;每个人的办公桌抽屉(栈)、随身笔记本(寄存器)则是私有的。
【易混对比】
| 资源 | 进程间 | 线程间 | 与第 17/18 题关联 |
|---|---|---|---|
| 地址空间 | 独立 | 共享 | 第 17 题:进程独立,线程共享 |
| 栈 | 独立 | 私有 | 第 18 题:ULT/KLT 都有私有栈 |
| 打开文件 | 独立(默认) | 共享 | 第 17 题:进程是资源单位 |
| 代码段 | 独立 | 共享 | 同型考点 |
换个问法:“多线程程序中,一个线程修改全局变量会影响其他线程吗?”——会,因为数据段是共享的;但若修改局部变量则不会,因为栈是私有的。与第 17 题(进程 vs 线程)和第 18 题(ULT vs KLT)连考。
【自测】 在同一进程的多线程环境中,下列资源中属于线程私有的是: A. 堆中的动态分配内存 B. 全局变量 C. 线程的栈和程序计数器 D. 打开的文件描述符
答:C。与执行现场绑定的栈、程序计数器、寄存器等为线程私有;堆、全局变量、打开文件表等由进程内各线程共享。 〈出处:408 真题同型题〉
【易错提醒】 ①判断依据是“该资源是否与执行现场绑定”,与现场绑定的一律私有。②堆是共享的而栈是私有的,这一对最容易混淆。③TCB 是线程存在的标志,与进程的 PCB 相对应,务必区分。
【知识关联】 本题考点:线程与切换。与第 17–22、27 题;面试:线程模型?切换开销来自哪?
【拓展延伸】 变式:比较进程切换与线程切换。Go M:N、Linux NPTL 是工程对照。(本题答案 D,以题干选项为准)
第20题
在采用写时复制(Copy-On-Write, COW)技术的系统中,父进程调用 fork 创建子进程后,下列说法正确的是( )。 A. 系统会立即完整复制父进程的整个地址空间,子进程与父进程此后互不影响 B. 子进程与父进程共享全部页表,任一方修改数据都会直接反映到另一方 C. 子进程初始与父进程共享物理页面,只有当任一方尝试写入某页时才真正复制该页 D. 写时复制只复制代码段,数据段和堆栈段仍然完全共享且不会分离
答案:C
考点定位:二、进程与线程管理——fork 与写时复制(COW),难度★★☆☆☆,是操作系统课程与互联网笔试中考察进程创建机制的高频考点。
【结论】 子进程初始与父进程共享物理页面,只有当任一方尝试写入某页时才真正复制该页,选 C。
【逐项辨析】
- A 错误——fork 采用写时复制正是为了避免立即的完整复制,且父子进程仍共享未写的页。
- B 错误——共享的是物理页面而非“同一份页表”,且写入会触发复制而不会互相污染。
- C 正确——准确描述了“先共享、写时才复制单页”的 COW 机制。
- D 错误——代码段本就常为只读共享,而数据段和堆栈段恰恰是写时复制保护的重点对象,一旦写入就会分离。
【知识点】 fork + COW 的完整工作机制:
fork() 调用前
+-------------------+ +-------------------+
| 父进程 | | 物理内存页面 |
| 页表: 虚页→物理页 |------->| 代码段(只读) |
+-------------------+ | 数据段(读写) |
| 堆栈段(读写) |
+-------------------+
fork() 调用后(初始状态)
+-------------------+ +-------------------+
| 父进程 | | 物理内存页面 |
| 页表项: 只读标记 |------->| 代码段(只读) |
+-------------------+ | | 数据段(读写→只读) |
| | 堆栈段(读写→只读) |
+-------------------+ | +-------------------+
| 子进程 | |
| 页表项: 只读标记 |---+
+-------------------+
父或子尝试写入数据段某页
|
v
触发写保护异常(缺页中断)
|
v
内核分配新物理页 + 复制原页内容
|
v
修改写方页表 → 指向新页,标记为可写
|
v
写方继续执行,未写方仍共享旧页COW 的核心收益在于避免大量“fork 后立即 exec”场景下的无用拷贝。在 shell 中执行命令时,shell 先 fork 出子进程,子进程立刻 exec 替换为新的程序映像——如果没有 COW,fork 时复制的大量页面会在 exec 后被全部丢弃,造成极大的时间和空间浪费。
【记忆锚点】 口诀——“fork 之后先共享,谁写谁复制,不写不花钱”。类比:COW 就像兄弟俩共用一本笔记本,一开始都只看(共享只读);当哥哥要在某页上做笔记时,管理员才给他复印那一页(复制单页),弟弟仍看原来的,兄弟俩从此在该页上内容不同。
【易混对比】
| 机制 | fork 传统复制 | fork + COW | 与第 12/13 题关联 |
|---|---|---|---|
| 复制时机 | 创建时立即全复制 | 延迟到写入时才复制 | 第 13 题:进程创建即创建 PCB |
| 复制粒度 | 整个地址空间 | 以页为单位 | 同型考点 |
| 共享时长 | 创建后即分离 | 未写之前一直共享 | 第 12 题:进程是动态实体 |
| 适用场景 | 早期 Unix | 现代 Linux/Unix | 同型考点 |
换个问法:“fork 后父子进程的页表项初始指向同一物理页,这些页的访问权限被设置为什么?”——只读(读/写页也会被临时标记为只读),以便在写入时触发缺页中断进行复制。与第 12 题(进程创建)和第 13 题(PCB)连考。
【自测】 在采用写时复制技术的系统中,父进程调用 fork 创建子进程后,若子进程立即调用 exec 执行新程序,则: A. 系统已完整复制父进程地址空间,exec 直接覆盖即可 B. 父子进程共享的所有页面都会在 exec 前被复制 C. 由于子进程未写入任何共享页,exec 前几乎没有页面被实际复制 D. 只有代码段被复制,数据段和堆栈段仍共享
答:C。COW 下 fork 后父子共享页面并标只读;子进程未写则不触发复制,exec 直接装入新映像,因此 exec 前几乎没有页面被实际复制。 〈出处:大厂面试高频〉
【易错提醒】 ①不要误认为 fork 会立刻复制全部内存,否则会低估其效率。②COW 复制的最小单位是页,不是整个段或整个进程。③子进程被创建后即使不 exec,其写过的页也会与父进程分离,未写的页仍共享。
【知识关联】 本题考点:fork 与写时复制(COW)。与第 26 题(fork/exec/exit/wait 语义)、第 28 题(进程的组成)、第 22 题(上下文切换开销)连考;面试追问:COW 下父子进程页表与物理页谁先复制?
【拓展延伸】 变式:大量僵尸如何清理(杀父进程让 init 收养)。Linux 用 ps 看 STAT=Z。(本题答案 C,以题干选项为准)
第21题
下列关于僵尸进程和孤儿进程的说法,正确的是( )。 A. 僵尸进程是已终止但父进程尚未调用 wait 回收其退出状态的进程,孤儿进程是被 init 收养后继续运行的进程 B. 僵尸进程仍占用 CPU 时间片继续运行,孤儿进程会被系统立即杀死 C. 僵尸进程是因为父进程先于子进程退出造成的,孤儿进程是因为子进程先于父进程退出造成的 D. 只要子进程调用 exit,系统就会自动释放其 PCB,因此不会出现僵尸进程
答案:A
考点定位:二、进程与线程管理——僵尸进程与孤儿进程,难度★☆☆☆☆,是进程生命周期中最常以概念辨析形式出现的送分题,也是面试追问 wait 回收机制的入口。
【结论】 选 A。子进程终止后内核只释放其内存等资源而保留 PCB,父进程不调用 wait 回收即成为僵尸进程;父进程先退出时尚未结束的子进程被 PID=1 的 init/systemd 收养,成为孤儿进程并继续运行。
【逐项辨析】
- A 正确——同时给出两者的成因与归宿:僵尸=已终止但父未 wait,孤儿=被 init 收养且继续运行。
- B 错误——僵尸进程已终止,不再参与调度、不占 CPU;孤儿进程不会被系统杀死,它只是换了父进程。
- C 错误——把成因说反了。僵尸源于“子先退出而父不回收”,孤儿源于“父先退出而子仍在运行”。
- D 错误——exit 只释放内存、文件描述符等资源,PCB 必须由父进程 wait/waitpid 回收,否则长期留在进程表中成为僵尸。
【知识点】 进程终止分两步:先“死”,再“葬”。
- 第一步由内核完成:释放地址空间、页表、打开文件等,但保留 PCB,因为退出状态码还要交给父进程读取。
- 第二步由父进程完成:父进程调用 wait/waitpid 取回退出状态,内核才撤销 PCB。缺第二步就产生僵尸。
- 若父进程先退出,子进程被 init(PID=1)收养,子进程结束时由 init 负责 wait 回收,因此孤儿进程不会退化成僵尸。
- 危害:僵尸不占 CPU 却占进程表项,数量过多会耗尽 PID 与内核内存,导致新进程 fork 失败(返回 -1,errno=EAGAIN)。
- 常规处理:父进程主动 wait/waitpid;捕获 SIGCHLD 后在信号处理函数中回收;或对 SIGCHLD 置 SIG_IGN;或采用“双重 fork”让中间进程立即退出,使真正的干活进程成为孤儿交由 init 回收。
| 维度 | 僵尸进程 | 孤儿进程 |
|---|---|---|
| 谁先退出 | 子进程先退出 | 父进程先退出 |
| 是否还运行 | 否,已终止 | 是,继续运行 |
| 占不占 CPU | 不占 | 正常占用 |
| 占用资源 | PCB 等少量内核资源 | 正常运行所需资源 |
| 归宿 | 父进程 wait 后消失 | 被 init 收养并由其回收 |
【推导过程】 两条时间线对比:
场景一 僵尸进程 场景二 孤儿进程
父: fork --- 运行 ----------> wait 父: fork --- 运行 -- 退出
子: \_ 运行 --- exit 子: \_ 运行 --------- 继续运行
| |
v v
PCB 保留 -> 僵尸 被 init(PID=1)收养
直到父调用 wait 才消失 结束时由 init 回收, 不产生僵尸
时间轴 ------------------------------------------------------>【记忆锚点】 口诀——“子死父不葬,变成僵尸;父死子无依,托给 init”。僵尸只留躯壳(PCB)不干活,孤儿换个家长照常生活。
【易混对比】
| 概念 | 关键判据 | 是否消耗 CPU | 是否还能被唤醒运行 |
|---|---|---|---|
| 僵尸进程 | 子终止且父未 wait | 否 | 否,已终止 |
| 孤儿进程 | 父先退出,子仍在运行 | 是 | 是 |
| 阻塞态进程 | 等 I/O 或事件,PCB 在等待队列 | 否 | 是 |
换种问法:“父进程调用 wait 之后,子进程的 PCB 是被谁撤销的?”——由内核在该次 wait 系统调用中撤销,而不是父进程自己动手删除。与第 26 题(wait 的语义)连考。
【自测】 某守护进程反复 fork 子进程执行任务却从不调用 wait,长期运行后 fork 返回 -1,最可能的原因是? A. 内存泄漏 B. 大量子进程已终止但未被回收,进程表被僵尸占满 C. 子进程变成孤儿被 init 杀死 D. 系统 PID 上限配置过小导致创建即失败
答:B。子进程退出后 PCB 未回收,僵尸持续堆积,耗尽进程表项或 PID,使 fork 失败。〈出处:408 真题同型题〉
【易错提醒】 ①僵尸进程不占 CPU,只占用 PCB 等少量内核资源,但数量过多会耗尽进程表;②孤儿进程不会“死亡”,而是被 init 收养;③识别关键在于“谁先退出”:子先退出且父不回收即僵尸,父先退出即孤儿。
【知识关联】 本题考点:僵尸进程与孤儿进程。与第 26 题(fork/exec/exit/wait)、第 90 题(ps/kill)、补-01(僵尸排障面试向)连考;面试追问:init/systemd 为什么能回收孤儿、僵尸占用的到底是什么资源?
【拓展延伸】 变式:大量僵尸如何清理(杀父进程让 init 收养)。Linux 用 ps 看 STAT=Z。(本题答案 A,以题干选项为准)
第22题
关于进程上下文切换,下列说法正确的是( )。 A. 上下文切换只是把 PC 寄存器的值换掉,开销可以忽略不计 B. 同一进程内的两个线程之间切换,一定要经过完整的内核上下文切换 C. 上下文切换需要保存和恢复 CPU 寄存器、程序计数器及页表等现场信息,并可能刷新 TLB 和缓存,因此有明显开销 D. 只要 CPU 处于空闲状态,就一定不会发生上下文切换
答案:C
考点定位:二、进程与线程管理——进程上下文切换的含义与开销,难度★★☆☆☆,是互联网笔试中结合性能分析考察的高频考点。
【结论】 选 C。上下文切换必须保存与恢复 CPU 寄存器、程序计数器、栈指针、页表基址等现场信息,并可能使 TLB 与 Cache 失效,因此是明显的纯开销操作。
【逐项辨析】
- A 错误——只换 PC 远远不够,通用寄存器、栈指针、程序状态字、页表基址都要保存,开销不可忽略。
- B 错误——同一进程内的线程共享地址空间,切换时不必更换页表基址,属于较轻量的切换。
- C 正确——完整概括了切换要保存的内容与开销来源(现场保存 + TLB/Cache 失效)。 严格说,切换换的是页表基址寄存器(x86 的 CR3 / ARM 的 TTBR),页表本体常驻内存不需保存恢复;题干选项中的「页表」按「页表基址」理解,答题时按 C 选。
- D 错误——CPU 空闲时调度器仍可能切换到就绪队列中的其他进程,或切入内核的空闲任务,空闲本身也是调度的结果。
【知识点】 进程上下文是内核为进程保存的运行现场,分三块:CPU 现场(通用寄存器、PC、SP、PSW)、内存现场(页表基址、内存指针)、资源现场(打开文件表、信号处理表)。切换只能在内核态完成,内核先把当前进程的现场写入其 PCB,再从目标进程的 PCB 恢复现场。开销分两类:直接开销(保存/恢复寄存器、切换页表基址、执行调度器代码)与间接开销(TLB 与 Cache 因地址空间变化而失效,后续访存变慢)。经验数据:单次切换约 3-5 μs,若每秒切换 1 万次,就吃掉 3%-5% 的 CPU 时间。
| 开销项 | 具体内容 | 是否随地址空间变化而恶化 |
|---|---|---|
| 保存/恢复寄存器 | 通用寄存器、PC、SP、PSW | 否 |
| 切换页表基址 | 改写 CR3 等页表基址寄存器 | 是 |
| TLB 失效 | 跨进程后地址翻译缓存作废,需重新填充 | 是 |
| Cache 冷启动 | 新进程工作集不在 Cache 中,命中率下降 | 是 |
| 调度器自身 | 选进程、维护就绪队列 | 否 |
【推导过程】 切换步骤:
进程 A 运行中
|
v
[1] 触发切换: 时间片用完 / A 阻塞 / 更高优先级进程到达 / 中断返回
[2] 陷入内核, 进入内核态
[3] 保存 A 的现场到 A 的 PCB (寄存器 / PC / SP / PSW / 页表基址)
[4] 调度器选出 B, 更新状态: A -> 就绪或阻塞, B -> 运行
[5] 跨进程切换: 换页表基址, 刷新 TLB (或按 ASID 打标签避免全刷)
[6] 恢复 B 的现场, 返回用户态
|
v
进程 B 运行【记忆锚点】 一句话——“切换 = 存档 + 读档,存读期间不干正事”。凡是“要换地址空间”的切换(进程间)最贵,只换寄存器的切换(同进程线程间)便宜。
【易混对比】
| 对比项 | 进程间切换 | 同进程内线程切换 | 模式切换(用户态<->内核态) |
|---|---|---|---|
| 是否更换地址空间 | 换页表基址 | 不换 | 不换 |
| TLB 是否失效 | 可能失效 | 不失效 | 不失效 |
| 是否发生调度 | 是 | 是 | 不一定 |
| 相对开销 | 最大 | 较小 | 最小 |
换种问法:“为什么线程切换比进程切换便宜?”——省掉页表切换与 TLB 失效这两笔大头。与第 27 题(线程模型)连考。
【自测】 同一进程内的两个线程相互切换,与两个不同进程之间切换相比,最主要的差别是什么?
答:线程切换不需要更换页表基址,地址空间不变,因而不会因换页表而使 TLB 失效,开销明显更小;两者都需要保存与恢复寄存器现场。〈出处:大厂面试高频〉
【易错提醒】 ①区分“进程切换”与“线程切换”,后者因共享地址空间而更轻;②切换开销来自保存恢复现场以及 TLB、Cache 的失效,而非调度算法本身;③上下文切换时间属于系统开销,是衡量调度性能的重要指标。
【知识关联】 本题考点:线程与切换。与第 17–22、27 题;面试:线程模型?切换开销来自哪?
【拓展延伸】 变式:比较进程切换与线程切换。Go M:N、Linux NPTL 是工程对照。(本题答案 C,以题干选项为准)
第23题
下列选项中,全部属于进程间通信(IPC)方式的一组是( )。 A. 共享内存、寄存器重命名、管道、信号 B. 消息传递、管道、信号、页面置换 C. 共享内存、消息传递、管道、信号 D. 共享内存、消息传递、信号、磁盘调度
答案:C
考点定位:二、进程与线程管理——进程间通信方式的分类,难度★☆☆☆☆,是国企笔试中考察 IPC 概念识别的常规题。
【结论】 选 C。IPC 是内核提供的跨进程数据交换与事件通知机制,共享内存、消息传递、管道、信号都在其列。
【逐项辨析】
- A 错误——寄存器重命名是 CPU 乱序执行中消除假数据相关的硬件技术,属于微架构优化,不是进程通信方式。
- B 错误——页面置换是虚拟内存管理中的页面淘汰算法,与 IPC 无关。
- C 正确——共享内存、消息传递、管道、信号四者都是操作系统提供的典型进程间通信方式。
- D 错误——磁盘调度是设备管理中为减少寻道时间而设计的 I/O 调度算法,不属于 IPC。
【知识点】 进程拥有独立地址空间,彼此不能直接访问对方数据,所以必须由内核提供 IPC。IPC 有两大基本模型:共享内存模型(双方把同一物理内存映射进各自页表,靠读写共享区交换数据)与消息传递模型(用 send/receive 原语传递消息,适合分布式环境)。在此之上衍生出多种具体机制:管道、命名管道、消息队列、信号量、信号、Socket。各方式的差异集中在五个维度:数据拷贝次数、是否需要额外同步、能否跨主机、是否保留消息边界、通信方向。
| 方式 | 数据拷贝次数 | 是否需额外同步 | 能否跨主机 | 是否保留消息边界 | 典型接口 |
|---|---|---|---|---|---|
| 匿名管道 pipe | 2 | 自带阻塞同步 | 否 | 否,字节流 | pipe |
| 命名管道 FIFO | 2 | 自带阻塞同步 | 否 | 否,字节流 | mkfifo |
| 消息队列 | 2 | 自带 | 否 | 是 | msgsnd/msgrcv |
| 共享内存 | 0-1 | 必须自行加锁 | 否 | 否 | shmget/mmap |
| 信号量 | 无数据 | 本身即同步工具 | 否 | 不适用 | sem_wait/sem_post |
| 信号 signal | 无数据 | 不适用 | 否 | 不适用 | kill/signal |
| Socket | 2 次以上 | 自带 | 是 | TCP 否 / UDP 是 | socket/send/recv |
【推导过程】 两大类模型的差别一眼看清:
共享内存模型: 进程 A <==== 同一物理页 ====> 进程 B (0 次拷贝, 但需自行加锁)
消息传递模型: 进程 A --copy--> 内核缓冲区 --copy--> 进程 B (2 次拷贝, 内核保证同步)【记忆锚点】 口诀——“共享内存传数据、信号传事件、信号量传许可、管道传字节流、Socket 传天下”。凡带“调度”“置换”“重命名”字眼的,一律不是 IPC。
【易混对比】
| 出现的关键词 | 所属领域 | 是否 IPC |
|---|---|---|
| 共享内存、消息队列、管道、信号、Socket | 进程间通信 | 是 |
| 页面置换、页面分配、地址重定位 | 内存管理 | 否 |
| 磁盘调度、缓冲区、DMA、中断 | 设备管理 | 否 |
| 寄存器重命名、分支预测、流水线 | CPU 微架构 | 否 |
换种问法:“下列哪些既能传数据又能做同步?”——管道、消息队列、Socket 自带同步;共享内存只能传数据,必须外挂信号量。与第 24 题(共享内存性能)连考。
【自测】 下列各组中,全部属于进程间通信方式的是? A. 共享内存、信号量、Socket、消息队列 B. 共享内存、虚拟内存、管道、信号 C. 消息队列、中断、信号、寄存器重命名 D. 管道、信号、磁盘调度、Socket
答:A。B 的虚拟内存属内存管理,C 的中断与寄存器重命名属硬件与设备范畴,D 的磁盘调度属设备管理。〈出处:国网真题库同型题〉
【易错提醒】 ①务必区分“进程通信”与“CPU 优化技术”“内存管理算法”“I/O 调度算法”;②共享内存与信号语义差别很大,前者传数据、后者传事件;③管道本质上也是一种基于内核缓冲区的通信方式,常被单独归类。
【知识关联】 本题考点:IPC。与补题 IPC 专题;面试:共享内存为何最快?如何同步?
【拓展延伸】 变式:选场景推荐 IPC 方式。Linux:pipe、shm、mq、socket 对照。(本题答案 C,以题干选项为准)
第24题
在众多进程间通信方式中,共享内存通常被认为速度最快,其主要原因是( )。 A. 数据直接在进程各自的地址空间中读写同一块物理内存,不需要经过内核在用户态与内核态之间反复拷贝数据 B. 共享内存由硬件直接完成数据同步,因此完全不需要任何同步机制 C. 共享内存使用 DMA 通道传输数据,绕过了操作系统的管理 D. 共享内存会把数据压缩后传输,从而减少了数据量
答案:A
考点定位:二、进程与线程管理——共享内存为何是最快的 IPC 方式,难度★★☆☆☆,是互联网笔试中考查 IPC 性能对比的经典考点。
【结论】 选 A。共享内存把同一块物理内存映射进多个进程的页表,双方直接在各自地址空间读写,省掉了数据在内核缓冲区的中转拷贝,因此速度最快。
【逐项辨析】
- A 正确——点明根本原因:直接读写同一物理内存,不需要在内核态与用户态之间反复拷贝数据。
- B 错误——共享内存完全不做同步,数据竞争必须由程序员用信号量或互斥量解决,硬件不会代劳。
- C 错误——DMA 是设备与内存之间的传输方式,与进程间共享内存无关;共享内存仍由操作系统通过页表映射管理。
- D 错误——共享内存不压缩数据,其优势来自减少拷贝次数,而非减少数据量。
【知识点】 消息传递类机制(管道、消息队列、Socket)的数据要走“用户空间 -> 内核缓冲区 -> 用户空间”这条路,即 2 次拷贝 + 2 次陷入内核 + 2 次返回用户态。共享内存则由内核在建立映射时把同一块物理页挂到多个进程的页表上,此后双方读写该区域与访问自己的局部变量无异,0 次拷贝、0 次模式切换。代价是:共享内存不提供任何同步,且需要自行管理数据结构(没有消息边界),因此工程上常与信号量配合——“共享内存负责快,信号量负责对”。此外,共享内存只能用于同一台主机。
| 通信方式 | 数据拷贝次数 | 模式切换次数 | 是否需要额外同步 |
|---|---|---|---|
| 匿名/命名管道 | 2 | 4 | 否 |
| 消息队列 | 2 | 4 | 否 |
| Socket | 2 以上 | 4 以上 | 否 |
| 共享内存 | 0-1 | 0 | 必须 |
【推导过程】 数据流对比:
管道 / 消息队列 (2 次拷贝)
用户A --copy1--> [内核缓冲区] --copy2--> 用户B
write read
共享内存 (0 次拷贝)
用户A <====== 同一物理页 (映射进双方页表) ======> 用户B【记忆锚点】 口诀——“共享内存快在零拷贝,慢在没同步;省了拷贝就要自己加锁”。答题落点永远是“拷贝次数”,不是“硬件更快”。
【易混对比】
| 对比项 | 共享内存 | 消息队列 | 管道 |
|---|---|---|---|
| 速度 | 最快 | 中等 | 中等 |
| 数据边界 | 无 | 有消息边界 | 无,字节流 |
| 同步 | 需外部信号量 | 内核保证 | 内核保证 |
| 可跨主机 | 否 | 否 | 否 |
换种问法:“共享内存既然最快,为什么工程中不无脑用它?”——因为同步与并发控制要自己写,易出数据竞争,且无法跨主机。与第 23 题(IPC 分类)连考。
【自测】 两个进程通过共享内存交换数据,读方偶尔读到“写了一半”的结构体,最直接的原因与对策是?
答:原因是共享内存不提供原子性与同步,写方尚未写完读方就读取;对策是引入信号量或互斥量做读写互斥(必要时再加双缓冲)。〈出处:大厂面试高频〉
【易错提醒】 ①“最快”的本质是少一次或多次数据拷贝以及更少的模式切换,不是硬件更特殊;②共享内存必须自行加锁,否则会出现数据不一致;③面试常追问“共享内存与管道的性能差异”,答题落点应放在拷贝次数上。
【知识关联】 本题考点:IPC——共享内存为何最快(省去用户态与内核态之间的数据拷贝)。与第 23 题(IPC 方式归类)、第 25 题(管道)连考;补题 IPC 专题。面试:共享内存为什么必须自行配同步?
【拓展延伸】 变式:共享内存最快但仍须自行配同步原语;管道/消息传递慢在数据要多次跨越用户态与内核态。(本题答案 A,以题干选项为准)
第25题
关于匿名管道(pipe)和命名管道(FIFO)的区别,下列说法正确的是( )。 A. 匿名管道和命名管道都必须由有亲缘关系的进程使用 B. 匿名管道有文件名,可以像普通文件一样被任意进程打开 C. 命名管道没有名字,只能在父子进程之间使用 D. 匿名管道只能用于有亲缘关系的进程且随进程结束而消失,命名管道以文件形式存在于文件系统中,无亲缘关系的进程也能通过路径打开
答案:D
考点定位:二、进程与线程管理——匿名管道与命名管道的区别,难度★★☆☆☆,是操作系统笔试题中管道相关的高频对比题。
【结论】 选 D。匿名管道靠 fork 后子进程继承文件描述符使用,只能用于有亲缘关系的进程且随进程结束消失;命名管道以 FIFO 特殊文件形式留在文件系统中,无亲缘关系的进程也能按路径打开。
【逐项辨析】
- A 错误——只有匿名管道要求亲缘关系,命名管道不受此限。
- B 错误——匿名管道没有名字,无法按文件名打开,只能靠继承描述符。
- C 错误——描述恰好说反:有名字的是命名管道,且它不限于父子进程。
- D 正确——完整准确地对比了两者在命名、亲缘关系与生命周期上的差异。
【知识点】 匿名管道由 pipe() 创建,内核返回一对读写描述符 fd[0](读)、fd[1](写),没有名字,只有 fork 后由子进程继承这对描述符才能通信,故限于亲缘进程,且随进程终止而消失。命名管道由 mkfifo() 创建,在文件系统中留下一个类型为 p 的特殊文件,任何知道路径的进程都能 open 它进行读写,故可用于无亲缘进程,且文件本身持久存在(除非 unlink)。两者共性:都是半双工的字节流通道,都基于内核缓冲区(Linux 默认容量 64 KB),读空管道会阻塞,缓冲区写满也会阻塞。
| 维度 | 匿名管道 pipe | 命名管道 FIFO |
|---|---|---|
| 创建方式 | pipe() | mkfifo() |
| 是否有文件名 | 无 | 有,类型为 p |
| 是否要求亲缘关系 | 必须 | 不要求 |
| 生命周期 | 随进程结束消失 | 持久存在于文件系统 |
| 使用方式 | 继承文件描述符 | open 路径 |
| 通信方向 | 半双工 | 半双工 |
| 消息边界 | 不保留,字节流 | 不保留,字节流 |
【推导过程】 两种管道的建立方式:
匿名管道: 父进程调用 pipe(fd) 后 fork, 描述符表被复制, 指向同一内核管道对象
父: pipe(fd) ---- fork ----+
+--------------------------+--------------------------+
父进程 写 fd[1] 子进程 读 fd[0]
[ 内核管道缓冲区 64KB ]
命名管道: 与亲缘关系无关, 靠路径会合
进程A --open("/tmp/fifo", O_WRONLY)--> [ FIFO 文件 ] --open(..., O_RDONLY)--> 进程B【记忆锚点】 口诀——“匿名靠继承,命名靠路径”;补一句“半双工、字节流、不保边界,双向要建两条”。
【易混对比】
| 对比项 | 管道 | 消息队列 | Socket |
|---|---|---|---|
| 是否保留消息边界 | 否 | 是 | TCP 否 / UDP 是 |
| 能否跨主机 | 否 | 否 | 能 |
| 需要亲缘关系 | 匿名需要 | 不需要 | 不需要 |
换种问法:“若管道写端全部关闭,读端 read 会怎样?”——立即返回 0,表示读到 EOF;反之若读端全部关闭,写端 write 会触发 SIGPIPE 信号并返回 EPIPE 错误。与第 23、24 题连考。
【自测】 某程序用匿名管道实现父子进程通信,父子各自同时往 fd[1] 写、又从 fd[0] 读,结果读到自己刚写入的数据。最可能的原因是?
答:匿名管道是半双工通道,同一对描述符被父子双方共用,双方都写会导致数据被任意一方读走;正确做法是建立两条管道,约定一条单向“父->子”、另一条“子->父”。〈出处:408 真题同型题〉
【易错提醒】 ①记忆口诀“匿名靠继承,命名靠路径”;②两者都是半双工,若需双向通信要建立两条管道;③管道是字节流,不保留消息边界,读方需自行处理分包。
【知识关联】 本题考点:进程间通信——匿名管道与命名管道(FIFO)的区别。与第 23–24 题(IPC 方式、共享内存为何最快)连考;补题 IPC 专题。面试:管道为何是半双工、命名管道靠什么解除亲缘限制?
【拓展延伸】 变式:匿名管道只能用于亲缘进程且随进程消亡;命名管道(FIFO)以文件形式存在于文件系统,无亲缘关系的进程也能按路径打开。(本题答案 D,以题干选项为准)
第26题
关于 fork、exec、exit、wait 四个系统调用的语义,下列说法正确的是( )。 A. exec 会创建新进程,并在新进程中执行指定程序 B. wait 用于终止子进程并强制释放其全部资源,包括尚未被读取的退出状态 C. exit 只能由父进程调用,用来结束整个进程组 D. fork 创建子进程并复制父进程的执行环境,exec 用新程序替换当前进程的正文段并保持 PID 不变,exit 终止进程,wait 阻塞等待子进程结束并回收其 PCB
答案:D
考点定位:二、进程与线程管理——fork/exec/exit/wait 的语义,难度★★☆☆☆,是笔试与面试中考查进程生命周期控制的核心考点。
【结论】 选 D。fork 复制父进程执行环境产生新进程,exec 用新程序替换当前进程的正文段而 PID 不变,exit 终止进程,wait 阻塞等待子进程结束并回收其 PCB。
【逐项辨析】
- A 错误——exec 不创建新进程,它只是用新程序替换当前进程的程序映像,进程数与 PID 都不变。
- B 错误——wait 是父进程回收子进程资源的动作,它并不会“强制释放尚未被读取的退出状态”,那个状态恰恰是 wait 要取回的对象。
- C 错误——exit 由任意进程自身调用以结束自己,并非只能由父进程调用,更不是用来结束整个进程组。
- D 正确——四项语义描述均准确。
【知识点】 四个系统调用串起进程的一生:fork 以写时复制(COW)方式复制父进程的地址空间产生子进程,子进程获得新 PID,从 fork 返回处继续执行;exec 不创建新进程,而是用指定可执行文件替换当前进程的代码段、数据段与堆栈,PID 保持不变,成功时不返回、失败返回 -1;exit 由进程自身调用,终止运行并把退出状态交给内核;wait/waitpid 由父进程调用,阻塞等待子进程终止,取回退出状态并回收其 PCB。经典组合是“fork 之后在子进程分支里立刻 exec”,既保留父进程又加载新程序。
| 系统调用 | 谁调用 | 作用 | 是否新建进程 | PID 是否变化 |
|---|---|---|---|---|
| fork | 任意进程 | 复制自身产生子进程(COW) | 是 | 子进程获得新 PID |
| exec | 进程自身 | 用新程序替换正文/数据/堆栈 | 否 | 不变 |
| exit | 进程自身 | 终止自己,交出退出状态 | 否 | 终止 |
| wait/waitpid | 父进程 | 等待子进程终止并回收 PCB | 否 | 不适用 |
【推导过程】 fork 返回值决定执行路径:
pid = fork();
if (pid < 0) { /* 创建失败 */ }
else if (pid == 0) { /* 子进程: 通常紧接着 exec 新程序 */ }
else { /* 父进程: pid 即子进程 PID, 可 waitpid 回收 */ }
时序: 父 --fork--> 子(新 PID, 与父并发) --exec--> 同一 PID 跑新程序 --exit--> 僵尸 --父 wait--> 消失【记忆锚点】 口诀——“fork 生、exec 换、exit 走、wait 葬”;再记“fork 变 PID,exec 不变 PID”。
【易混对比】
| 对比项 | fork | exec | vfork |
|---|---|---|---|
| 是否产生新进程 | 是 | 否 | 是 |
| 地址空间 | 复制(写时复制) | 被替换 | 共享父进程地址空间,父进程阻塞 |
| 典型用途 | 并发处理 | 加载新程序 | 紧接 exec 时省一次复制 |
换种问法:“子进程退出后成为僵尸,是谁把它清除的?”——是父进程的 wait/waitpid,与第 21 题连考。
【自测】 某进程调用 exec 成功加载新程序后,PID 是否改变?原程序中定义的全局变量还在吗?
答:PID 不变;原进程的代码段、数据段、堆栈被新程序完全替换,原全局变量不复存在;exec 成功后不返回,只有失败才返回 -1。〈出处:408 真题同型题〉
【易错提醒】 ①fork 改变 PID,exec 不改变 PID;②fork 的返回值在父子进程中不同(父得子 PID,子得 0),这是区分执行路径的关键;③父进程若不调用 wait,子进程终止后会变成僵尸进程。
【知识关联】 本题考点:fork/exec/exit/wait 四个系统调用的语义(本题即该考点本体)。与第 20 题(fork 与 COW)、第 21 题(僵尸/孤儿)、第 90 题(ps/kill)构成进程管理链;面试追问:waitpid 与 SIGCHLD 的关系、exec 之后 PID 变不变?
【拓展延伸】 变式:大量僵尸如何清理(杀父进程让 init 收养)。Linux 用 ps 看 STAT=Z。(本题答案 D,以题干选项为准)
第27题
关于线程的实现方式与多线程模型,下列说法正确的是( )。 A. 多对一模型中,多个用户级线程被映射到多个内核线程,因此可以充分利用多核并行 B. 一对一模型中,每个用户级线程对应一个内核线程,一个线程阻塞不会影响其他线程,可充分利用多核,但线程数量受内核资源限制 C. 多对多模型把多个用户级线程映射为更少或相等的内核线程,兼顾并发能力与开销,但绝不允许用户级线程数量超过内核线程 D. 用户级线程的切换必须陷入内核,因此比内核级线程切换更慢
答案:B
考点定位:二、进程与线程管理——线程实现方式与多线程模型,难度★★☆☆☆,是笔试中考察线程模型分类的常考点。
【结论】 选 B。一对一模型中每个用户级线程对应一个内核线程,一个线程阻塞不影响其他线程,可充分利用多核,代价是线程数量受内核资源限制。
【逐项辨析】
- A 错误——多对一模型是把多个用户级线程映射到一个内核线程,内核只看到一个执行体,既无法多核并行,还会阻塞传染。
- B 正确——准确描述了一对一模型的能力与代价。
- C 错误——多对多模型恰恰允许用户级线程数多于内核线程数,这正是它的设计目的。
- D 错误——用户级线程切换在用户态由线程库完成,不需要陷入内核,通常比内核级线程切换更快。
【知识点】 线程实现分两类。用户级线程(ULT)由用户态线程库管理,内核只看到进程,切换不陷入内核、速度快,但一个线程阻塞会使整个进程挂起,也无法在多核上真正并行。内核级线程(KLT)由内核直接管理与调度,可被分配到不同 CPU 并行执行,但创建、切换都要陷入内核,开销更大。两者的映射关系构成三种模型:多对一(m 个用户线程 -> 1 个内核线程,并发差、有阻塞传染)、一对一(1:1,并发强但线程数受限)、多对多(m 个用户线程 -> n 个内核线程,且允许 m > n,兼顾并发与开销)。
| 维度 | 用户级线程 ULT | 内核级线程 KLT |
|---|---|---|
| 管理者 | 用户态线程库 | 操作系统内核 |
| 切换开销 | 小,无需陷入内核 | 大,需陷入内核 |
| 能否多核并行 | 不能 | 能 |
| 阻塞影响 | 一个阻塞则整个进程挂起 | 只阻塞该线程 |
| 内核调度单位 | 进程 | 线程 |
| 模型 | 映射关系 | 多核并行 | 阻塞传染 | 代表实现 |
|---|---|---|---|---|
| 多对一 | m : 1 | 不能 | 有 | 早期绿色线程 |
| 一对一 | 1 : 1 | 能 | 无 | Linux NPTL、Windows 线程 |
| 多对多 | m : n, m >= n | 能 | 基本消除 | Solaris、Go 的 goroutine 调度 |
【推导过程】 阻塞传染的直观演示:
多对一: 内核只看到一个内核线程 K
用户线程 T1 --- 阻塞式 read ---> K 被挂起
用户线程 T2 ---> 无法运行 (整个进程挂起)
一对一: 每个用户线程独立对应一个内核线程
T1 -> K1 (阻塞) T2 -> K2 (照常运行) T3 -> K3 (可在另一核并行)【记忆锚点】 口诀——“用户级快但不并行,内核级能并行但费;多对一传染阻塞,一对一最直接,多对多最均衡”。
【易混对比】
| 对比项 | 线程切换 | 进程切换 | 用户级线程切换 |
|---|---|---|---|
| 是否陷入内核 | 是 | 是 | 否 |
| 是否换页表 | 否 | 是 | 否 |
| 开销 | 较小 | 最大 | 最小 |
换种问法:“为什么用户级线程的切换比内核级线程更快?”——因为不陷入内核、不换页表,与第 22 题(上下文切换开销)连考。
【自测】 某系统采用多对一模型实现用户级线程,其中一个线程执行阻塞式 read 系统调用,会发生什么?
答:内核只看到一个内核线程,该线程阻塞会使整个进程被挂起,进程内所有用户级线程都无法继续运行,也无法在另一核上并行。〈出处:大厂面试高频〉
【易错提醒】 ①用户级线程“快但不并行”,内核级线程“能并行但开销大”;②多对一的关键缺陷是阻塞传染,一个线程阻塞即导致整个进程挂起;③多对多模型的核心优势是用户线程数可大于内核线程数,同时保留并行能力。
【知识关联】 本题考点:线程与切换。与第 17–22、27 题;面试:线程模型?切换开销来自哪?
【拓展延伸】 变式:比较进程切换与线程切换。Go M:N、Linux NPTL 是工程对照。(本题答案 B,以题干选项为准)
第28题
关于进程的组成,下列说法正确的是( )。 A. 进程由程序段和数据段组成,PCB 属于操作系统内核,不属于进程的组成部分 B. 进程由程序段、数据段和 PCB 三部分组成,其中 PCB 是进程存在的唯一标志,记录了进程的 PID、状态、程序计数器和资源清单等信息 C. 进程就是一段可执行程序,同一个程序只能对应一个进程 D. 进程的 PCB 在进程运行结束后仍永久保留,用于后续调度决策
答案:B
考点定位:二、进程与线程管理——进程的组成(程序段、数据段、PCB),难度★☆☆☆☆,是国企笔试中考查进程基本概念的基础题。
【结论】 选 B。进程实体由程序段、数据段和 PCB 三部分组成,其中 PCB 是进程存在的唯一标志,记录了 PID、状态、程序计数器与资源清单等信息。
【逐项辨析】
- A 错误——PCB 正是进程的组成部分,而且是最关键的部分,不能说它“不属于进程”。
- B 正确——完整给出了进程的三部分构成以及 PCB 的地位与内容。
- C 错误——进程是程序的一次执行过程,是动态的;程序是静态的,同一程序可被多次加载形成多个进程。
- D 错误——PCB 在进程终止并被父进程回收(wait)后即被撤销,并非永久保留。
【知识点】 进程实体由三部分组成:程序段(可执行代码,描述“做什么”)、数据段(全局变量、堆、栈等运行数据,描述“操作对象”)、PCB(进程控制块),三者合称进程映像。PCB 是操作系统感知进程存在的唯一依据,被称为进程存在的唯一标志,其内容按用途分三类:标识信息(PID、父进程 PID、用户 ID)、现场信息(程序计数器、各寄存器值、栈指针、页表基址)、控制信息(进程状态、优先级、内存指针、打开文件表、记账信息、信号处理表)。进程与程序是多对多关系:同一程序可对应多个进程,一个进程也能通过 exec 先后运行不同程序。
+-------------------------------------------+
| 进程实体 |
| +-------------------------------------+ |
| | 程序段 (代码, 只读, 可被多进程共享) | | 做什么
| +-------------------------------------+ |
| | 数据段 (全局变量 / 堆 / 栈) | | 操作谁
| +-------------------------------------+ |
| | PCB ---------------------------- | | 我是谁 + 干到哪
| | PID / 父 PID / 用户 ID | |
| | 状态 / 优先级 | |
| | PC / 通用寄存器 / 栈指针 / 页表基址 | |
| | 内存指针 / 打开文件表 / 记账信息 | |
| +-------------------------------------+ |
+-------------------------------------------+【记忆锚点】 口诀——“程序段 + 数据段 + PCB,三件套;PCB 一撤,进程即亡”。记“PCB 是进程的身份证 + 病历本 + 存档文件”。
【易混对比】
| 对比项 | 进程 | 程序 |
|---|---|---|
| 性质 | 动态,一次执行过程 | 静态,一组指令与数据 |
| 存在时间 | 有生命周期 | 长期保存 |
| 组成 | 程序段 + 数据段 + PCB | 指令 + 数据 |
| 对应关系 | 多对多 | 多对多 |
换种问法:“PCB 中的程序计数器什么时候被写入?”——每次进程被剥夺 CPU 时,内核把当前 PC 存进其 PCB,这也正是第 22 题所说的上下文保存;进程终止后 PCB 由父进程 wait 回收,与第 21、26 题连考。
【自测】 同一个可执行文件被先后运行 3 次,系统中共有几个 PCB?为什么?
答:3 个。每次运行都产生一个独立进程,各有一套 PID、寄存器现场与资源清单;PCB 是进程存在的唯一标志,进程与程序是多对多关系。〈出处:国网真题库同型题〉
【易错提醒】 ①牢记“PCB 是进程存在的唯一标志”,这是判断题的高频陷阱;②进程是动态概念,程序是静态概念;③进程与程序不是一一对应,可多对多。
【知识关联】 本题考点:进程组成(程序段+数据段+PCB)与 PCB 的地位。同库题群:第12题(进程 vs 程序)、第13题(PCB 是进程存在的唯一标志)、第14–16题(三态与 PCB 现场信息);补题相关:补-01(僵尸进程残留的正是 PCB 表项)、补-05/补-06(上下文切换保存/恢复 PCB 现场)。Linux机制:内核中 PCB 对应 task_struct,可通过 ps -eo pid,ppid,stat,cmd 或 /proc/<pid>/status、/proc/<pid>/stat 查看状态与现场相关信息;fork 创建新 task_struct,wait/exit 负责释放。面试追问:①PCB 里通常有哪些信息(标识、现场、控制三类)?②进程撤销后 PCB 何时消失(父进程 wait 或被 init 收养回收之后)?
【拓展延伸】 变式:同一可执行文件运行 N 次有几个 PCB(N 个,进程与程序多对多);「程序代码能否作为进程存在的唯一标志」→ 不能,代码可被多进程共享。工程:容器/PID namespace 下 PCB 表项更易被漏 wait 打满,入口进程常用 tini/dumb-init 充当回收者(见补-01)。诊断链:ps --forest 看进程树 → cat /proc/<pid>/status 查看 Name/State/PPid。(本题答案 B,以题干选项为准)