计算机操作系统进程与线程的组织与控制 - 指南

进程与线程的组织与控制

什么”与“怎么变”理解了进程/线程及其状态转换。要让这些抽象真正运行起来,操作系统必须“有账可查、有队可排、有章可循”。换句话说,系统得一套就是在前两节中,我们从“数据结构来描述每个执行实体的关键信息,还需要一套控制流程如何发生的。就是来创建、撤销、阻塞、唤醒与切换它们。本节围绕这两个核心,依次说明进程与线程在内核中的组织方式,以及常见控制动作

进程的组织:PCB 与队列

为了在成百上千个并发活动中“点名到人”,操作系统会为每个进程建立一份“身份证”,这就是进程控制块(PCB)。可能把 PCB 看成被平台严密管理的一张卡片,里面装着让进程可被识别、可被调度的一切关键信息。典型地,PCB 至少需要记录以下几类内容:标识与主要属性(如进程标识符、优先级)、处理机现场(如脚本计数器与通用寄存器的保存区)、内存映射与地址空间信息(如页表或段表的引用)、资源使用情况(如已打开文件与所占用的设备)、进程状态与统计信息等。恰是依赖这张“卡片”,内核才能搞定从保存现场到恢复现场的一系列操作。

有了“身份证”,还需要“排队规则”。系统通常把处于相同状态或相近处理策略的进程组织成队列集合。最常见的是就绪队列阻塞队列:前者存放“已经具备执行条件、只差 CPU”的进程,后者按等待的事件类型分门别类地挂接“离开 CPU、等待事件”的进程。为了兼顾公平与响应,很多系统还会把就绪队列按优先级分层,或者采用多级反馈队列等策略;无论策略如何变化,背后的组织思想都很一致——PCB 作为节点,通过指针或索引被串联成各类队列,调度器据此高效地选择下一个要运行的目标。这样,“有账可查”与“有队可排”便具备了基本形态。

进程的控制:创建、撤销、阻塞/唤醒与切换

为了展示这些控制动作如何落地,我们用顺畅的工作流把它们串起来。

操作系统创建进程的过程如下:首先分配并初始化一份新的 PCB,登记基本标识、初始优先级与初始状态等信息;接着为即将运行的程序准备必要的运行环境,例如建立地址空间映射、分配内核栈与用户栈、设置脚本计数器的起始位置;随后根据系统策略装入可执行映像或继承父进程的资源视图,设置好入口参数与初始寄存器现场;最后把该进程的状态置为“就绪”,将其 PCB 插入就绪队列,等待调度分派。在支持层次结构的系统中,新建的进程还会登记父子关系,从而在进程树上占据一个节点。

当进程结束或被撤销时,内核会做一组对称的清理动作:记录退出原因与返回码,关闭还未关闭的文件与设备,回收其占用的内存与内核对象,把 PCB 从所在队列摘除并最终释放。结束的触发既可能来自程序自然运行完毕,也可能来自异常或外部控制请求;如果父进程需要获知子进程的结束状态,还会发生一次同步等待与状态获取的配合。

进程在运行过程中常常需要等待事件,例如等待磁盘 I/O 完成或某个同步条件成立。此时继续占用 CPU 并不能推进工作,于是进程将从“运行”转为“阻塞”,其 PCB 会被移动到相应的阻塞队列,等待事件发生。当事件完成后,一个与之关联的内核路径(例如中断服务例程或内核回调)会把该进程的状态改回“就绪”,并把 PCB 重新插回就绪队列,从而回到可被调度的轨道上。由此,阻塞与唤醒形成了围绕“事件”的一收一放。

为了把 CPU 交给下一个合适的进程,系统必须完成一次上下文切换。切换的关键在于“先保存、后恢复”:内核先把当前进程的寄存器现场等运行关键信息写回到其 PCB 中,并把它的状态改为“就绪”或“阻塞”;随后,调度器按照策略从就绪队列中挑选目标,把目标进程的现场从 PCB 读出装入处理器,更新内核中的当前进程指针,最后把控制权交还给新进程继续执行。需要注意两点:其一,上下文切换用户态/内核态的模式切换并不是同一概念——一次系统调用会发生模式切换,但未必更换进程;其二,在同一进程内部不同线程之间的切换,一般不需要更换地址空间,因此开销通常小于跨进程的切换。

线程的组织与控制:TCB、线程队列与典型动作

当系统采用内核支持的线程时,线程会作为内核可调度的实体拥有自己的线程控制块(TCB)。TCB 与 PCB 的作用相似,但更聚焦于“执行现场”与“调度属性”,例如保存线程的寄存器现场、运行栈指针、线程状态、优先级、与所属进程的链接等。内核据此把处于不同状态的线程组织到就绪线程队列阻塞线程队列中;调度器直接从就绪线程队列挑选目标,把处理机时间片分派给“线程”,从而建立以线程为粒度的抢占式调度。

在线程层面,各种控制动作与进程层面高度同构。以创建线程为例:系统或线程库会分配并初始化一份 TCB,设置入口函数、参数与初始栈帧,建立必要的内核或用户态栈,随后把线程状态置为“就绪”,插入就绪线程队列等待调度。线程结束或被撤销时,平台回收其栈与内核对象,更新 TCB 状态并摘除队列节点。阻塞与唤醒也遵循相同的“等待事件—事件完成”的节拍;差别在于影响范围——线程共享所属进程的大多数资源,因此单个线程的异常可能殃及整个进程。在上下文切换方面,若仅在线程之间切换且保持在同一进程内,核心是保存/恢复寄存器与栈指针;而跨进程的切换还需要更换地址空间映射,开销更高。至于采用用户级线程库的系统,则由线程库在用户态维护 TCB 与线程队列,并在合适的时机进行用户态的切换;这类构建的阻塞与并行特征,已在上一节作过区分,此处不再赘述。

控制动作的触发与内核路径

最后把这些控制动作放回运行时的时序中,就能看见它们是如何被触发并结束闭环的。常见的触发源主要有三种:其一是系统调用,例如显式地请求创建进程或线程、发起阻塞型 I/O、等待子进程结束等;其二是时钟中断,它在时间片末尾把当前运行实体送回就绪队列,从而推动抢占式调度;其三是设备中断/事件回调依靠这条始终运转的路径,进程与线程在系统中得以被有序地组织与有效地控制。就是,当 I/O 搞定或外部事件发生时,负责把相关的阻塞实体唤回就绪态。它们共同构成了“陷入内核—执行管理—返回用户态”的控制路径:用户态发出请求或被动接收中断,内核据此更新 PCB/TCB 与各类队列,随后恢复选中的目标继续运行。正

posted @ 2025-09-09 10:35  yjbjingcha  阅读(8)  评论(0)    收藏  举报