# 6.5进程

## 阅读入口

* [进程](/knowledge/cs/operating-systems/process/)
* [进程调度](/knowledge/cs/operating-systems/process-scheduling/)

## 程序与进程

程序描述要执行的指令和数据，可以以可执行文件、脚本等形式存在。**进程**是程序运行时由操作系统管理的执行环境，包括地址空间、已打开的资源和管理信息。一个程序可以启动多个进程，它们的运行状态彼此独立，但可以共享某些内存或资源。

进程中的**线程**是调度和执行的单位：同一进程的线程通常共享进程地址空间与资源，各自具有程序计数器、寄存器和调用栈等执行状态。下面用单线程进程的简化模型说明状态变化。

[来源：进程](/knowledge/cs/operating-systems/process/#definition)

先区分程序与进程，再引入单线程模型中的地址空间与状态。单核示例中的调度结论不应直接推广到多核或多线程情形。

## 地址空间、状态与内核管理

### 地址空间

进程使用虚拟地址空间。一个常见的简化布局包括代码、已初始化数据、零初始化的静态数据、堆和调用栈：

| 区域     | 常见用途                   |
| :----- | :--------------------- |
| 代码     | 存放可执行指令，通常可以只读映射       |
| 数据与BSS | 分别容纳已初始化数据与需要零初始化的静态存储 |
| 堆      | 为动态分配提供空间              |
| 栈      | 保存调用过程需要的状态与局部数据       |

具体分段、地址顺序和增长方向由平台、程序与运行时决定，不是所有系统都遵循同一张示意图。进程地址空间可以映射共享内存或同一份只读代码，独立的虚拟地址空间不代表每个物理页都必须单独复制。

### 状态与转换

在单线程进程的五状态模型中，进程可以处于新建、就绪、运行、阻塞或终止状态：

| 状态 | 含义                |
| :- | :---------------- |
| 新建 | 正在创建，尚未进入就绪队列     |
| 就绪 | 可以运行，等待获得CPU      |
| 运行 | 正在CPU上执行          |
| 阻塞 | 等待I/O或其他事件，暂时不能继续 |
| 终止 | 已退出，系统正在或已经处理其资源  |

调度使就绪转为运行；抢占或时间片到期可使运行转为就绪；需要等待的操作使运行转为阻塞；事件完成后阻塞转为就绪。只有真正需要等待时，I/O请求才会导致阻塞。

这是教学模型。实际系统常以线程为调度单位；多线程进程可以同时有运行、就绪或等待中的线程，不能简单用一个状态概括所有线程。

### 内核管理的信息

内核维护进程标识、地址空间、资源和调度所需信息。这些管理信息通常概括为**进程控制块**（PCB），具体结构和名称随操作系统不同。

页表参与虚拟地址到物理内存的映射与访问权限检查。文件描述符表让进程引用已打开的文件、管道或套接字等资源；不同描述符也可能引用共享的打开文件状态，不能一概认为文件位置总是各自独立。

### 上下文切换

当CPU转去执行另一个线程时，内核需要保存和恢复必要的执行状态，并按需要切换地址空间。切换发生在线程之间；同一进程内的线程通常共享地址空间，跨进程切换则可能需要更换地址空间相关状态。调度器决定下一个运行的线程，见[进程调度](/knowledge/cs/operating-systems/process-scheduling/)。

切换需要时间，期间CPU执行的是内核的保存、恢复和调度工作；实际代价依赖平台、缓存状态和切换类型，不能仅凭这段示意给出固定数值。

[来源：进程](/knowledge/cs/operating-systems/process/#properties)

本节先用单线程模型理解五状态，再联系地址空间、资源记录和上下文切换；实际系统常以线程为调度单位。

## 学习安排

[6.3硬件中断与异常](/courses/cs/csintro/6.3/) 和[6.4软件中断与系统调用](/courses/cs/csintro/6.4/) 讲的是事件怎样打断执行流、又怎样进入内核；这一节把视角落到被中断的实体上：内核为每个运行中的程序维护一个进程，`Running → Blocked`往往由6.4的系统调用触发，`Blocked → Ready`通常由I/O完成的中断或事件通知触发。读完进程再看[6.6文件](/courses/cs/csintro/6.6/)，已打开文件表正好接上文件描述符那条线。

建议顺序：先分清程序与进程，再看常见地址空间中各区域的用途；接着用五状态模型和转换条件把生命周期串起来；然后看PCB、页表、已打开文件表分别记什么；最后读上下文切换和调度算法。调度放在最后，因为它操作的对象是就绪队列，要先有状态模型才能理解队列里放的是谁。

## 课程约定

* 课件按单核CPU讲状态：同一时刻只有一个进程处于运行状态。
* 状态模型采用新建、就绪、运行、阻塞/等待、终止五状态。
* 判断状态转换时按触发事件归类：时间片用完或被抢占回到就绪，请求I/O或等待事件进入阻塞，I/O完成或事件发生回到就绪。
* 调度算法沿用课件缩写：FCFS、SJF、RR；SJF的抢占式变体称为最短剩余时间优先。
* 时间片10–100 ms是课件给出的典型范围，实际取值由系统配置决定。

## 易错点

* 程序是静态的可执行文件，进程是它的一次执行；同一个程序启动两次可以得到两个进程，各自拥有进程身份和虚拟地址空间，也可能共享部分映射或资源。
* 阻塞的进程不是“排在后面的就绪进程”：即使把CPU分给它，它要等的事件没有发生，仍然不能运行。
* `Running → Ready`与`Running → Blocked`的触发不同：前者是时间片用完或被抢占，后者是进程主动请求I/O或等待事件。
* 上下文切换不是进程完成：切换只保存和恢复现场，被换下的进程按原因进入就绪或阻塞，之后还会被再次调度。
* 时间片过短会增加切换开销，过长会让RR退化成FCFS；两个极端都要能判断。
* SJF的平均等待时间最优有前提：所有进程同时到达且CPU执行时间已知。实际系统只能预测，长进程还可能饥饿。
* 常见可执行文件中的BSS用于零初始化的静态存储；具体加载和地址布局取决于平台。

## 复习要点

判断状态转换时先问“谁触发了这次转换”：时钟中断把运行进程送回就绪，I/O请求把它送入阻塞，I/O完成中断把它送回就绪。这个顺序比背箭头更稳。

比较调度算法时固定看四列：是否抢占、平均等待时间、是否饥饿、适合的场景。RR的取舍集中在时间片长度，优先级调度的取舍集中在老化是否启用。
