进程
定义
程序描述要执行的指令和数据,可以以可执行文件、脚本等形式存在。进程是程序运行时由操作系统管理的执行环境,包括地址空间、已打开的资源和管理信息。一个程序可以启动多个进程,它们的运行状态彼此独立,但可以共享某些内存或资源。
进程中的线程是调度和执行的单位:同一进程的线程通常共享进程地址空间与资源,各自具有程序计数器、寄存器和调用栈等执行状态。下面用单线程进程的简化模型说明状态变化。
性质
地址空间
进程使用虚拟地址空间。一个常见的简化布局包括代码、已初始化数据、零初始化的静态数据、堆和调用栈:
| 区域 | 常见用途 |
|---|---|
| 代码 | 存放可执行指令,通常可以只读映射 |
| 数据与BSS | 分别容纳已初始化数据与需要零初始化的静态存储 |
| 堆 | 为动态分配提供空间 |
| 栈 | 保存调用过程需要的状态与局部数据 |
具体分段、地址顺序和增长方向由平台、程序与运行时决定,不是所有系统都遵循同一张示意图。进程地址空间可以映射共享内存或同一份只读代码,独立的虚拟地址空间不代表每个物理页都必须单独复制。
状态与转换
在单线程进程的五状态模型中,进程可以处于新建、就绪、运行、阻塞或终止状态:
| 状态 | 含义 |
|---|---|
| 新建 | 正在创建,尚未进入就绪队列 |
| 就绪 | 可以运行,等待获得CPU |
| 运行 | 正在CPU上执行 |
| 阻塞 | 等待I/O或其他事件,暂时不能继续 |
| 终止 | 已退出,系统正在或已经处理其资源 |
调度使就绪转为运行;抢占或时间片到期可使运行转为就绪;需要等待的操作使运行转为阻塞;事件完成后阻塞转为就绪。只有真正需要等待时,I/O请求才会导致阻塞。
这是教学模型。实际系统常以线程为调度单位;多线程进程可以同时有运行、就绪或等待中的线程,不能简单用一个状态概括所有线程。
内核管理的信息
内核维护进程标识、地址空间、资源和调度所需信息。这些管理信息通常概括为进程控制块(PCB),具体结构和名称随操作系统不同。
页表参与虚拟地址到物理内存的映射与访问权限检查。文件描述符表让进程引用已打开的文件、管道或套接字等资源;不同描述符也可能引用共享的打开文件状态,不能一概认为文件位置总是各自独立。
上下文切换
当CPU转去执行另一个线程时,内核需要保存和恢复必要的执行状态,并按需要切换地址空间。切换发生在线程之间;同一进程内的线程通常共享地址空间,跨进程切换则可能需要更换地址空间相关状态。调度器决定下一个运行的线程,见进程调度。
切换需要时间,期间CPU执行的是内核的保存、恢复和调度工作;实际代价依赖平台、缓存状态和切换类型,不能仅凭这段示意给出固定数值。
例子
等待文件读取
在单线程模型中,进程发起读取后若必须等待I/O,就从运行转为阻塞;事件完成后进入就绪队列,再由调度器选择运行。若数据已经可用而调用无需等待,则不一定经历阻塞。
交互探索
选择调度、等待和完成等事件,查看简化的进程状态转换。它展示单线程模型,不代表一个多线程进程的全部线程状态。
进程因哪些事件改变状态?
按事件推进进程,查看就绪、运行和阻塞之间的转换。
正在准备演示…
练习
关于程序与进程的关系,下列哪一项正确?
参考解答
程序描述指令和数据,可以以可执行文件、脚本等形式存在;进程是一次运行中的执行环境,包含地址空间和资源,其线程还有各自的执行状态。同一个程序可以启动多个进程。
关于进程的内存布局,下列叙述哪些正确?
参考解答
堆和栈的实际布局与增长方向取决于体系结构和运行时;其余三项描述的是常见的进程布局。
进程等待键盘输入时,处于五状态模型中的哪个状态?
参考解答
等待键盘输入属于等待事件。此时进程即使获得CPU也不能继续执行,因此处于阻塞状态;等输入到达后才会转为就绪。
在单核CPU上,一个正在运行的进程因时间片用完而被换下,它会转到哪个状态?
参考解答
时间片用完只剥夺CPU,进程所需的其他资源仍然具备,所以回到就绪队列等待下一次调度,而不是进入阻塞。
下列哪些结构由内核为每个进程分别维护?
参考解答
在这个简化模型中,内核记录每个进程的管理信息、地址空间和文件描述符;底层内存或打开文件描述可以在进程间共享。就绪队列用于调度,并不专属于某一个进程。
上下文切换的开销来自哪里?
参考解答
上下文切换的核心工作是保存和恢复程序计数器与寄存器等现场,这段时间CPU执行内核的切换工作,而不是应用线程的计算。进程被换下并不等于结束,PCB和页表都保留着。