一、进程的五状态模型与转换

进程在生命周期中会在不同状态之间切换,最经典的五状态模型完整描述了进程从创建到销毁的全过程。

1. 五种核心状态

  1. 新建态(New):进程正在被创建,OS 正在为其分配资源、初始化 PCB,尚未进入就绪队列。
  2. 就绪态(Ready):进程已经准备好运行,只差 CPU 资源,等待调度程序分配 CPU 时间。
  3. 运行态(Running):进程获得 CPU,正在执行指令。单 CPU 系统同一时刻只有一个进程处于运行态。
  4. 阻塞态(Blocked/Waiting):进程因等待某事件(如 I/O 完成、信号量、用户输入)而暂停运行,即使 CPU 空闲也无法执行。
  5. 终止态(Terminated):进程执行完毕或异常退出,OS 正在回收其资源、移除 PCB。

2. 状态转换条件与实例

表格

转换方向 触发条件 实例
新建 → 就绪 进程创建完成,资源分配完毕 双击打开软件,程序加载完成后进入就绪队列
就绪 → 运行 调度程序选中该进程,分配 CPU 使用权 时间片轮转调度中,轮到当前进程执行
运行 → 就绪 时间片用完;有更高优先级进程进入就绪态 进程执行 20ms 后时间片耗尽,回到就绪队列排队
运行 → 阻塞 进程请求 I/O;等待同步事件;主动休眠 进程调用scanf()等待用户键盘输入,进入阻塞
阻塞 → 就绪 等待的事件已经发生 用户输入完成,I/O 中断触发,进程被唤醒
运行 → 终止 程序正常结束;出现致命错误;被其他进程杀死 程序执行完 return 0;程序崩溃;任务管理器结束进程

关键注意点

阻塞态不能直接转换为运行态:阻塞的进程事件完成后,必须先回到就绪态,等待调度程序统一分配 CPU。

二、进程控制块(PCB)与上下文切换

PCB 是 OS 管理进程的核心数据结构,系统通过 PCB 感知进程的存在。进程创建时生成 PCB,进程销毁时回收 PCB。

PCB 核心内容

  1. 进程标识信息:进程 ID(PID)、父进程 ID、用户 ID,用于唯一标识进程。
  2. 处理机状态信息:通用寄存器、程序计数器(PC)、程序状态字(PSW)、栈指针等,用于上下文切换时保存 / 恢复现场。
  3. 进程调度信息:进程状态、优先级、调度参数、等待时间、已执行时间。
  4. 资源管理信息:内存地址空间、打开的文件列表、占用的 I/O 设备、信号量列表。

上下文切换的完整过程(实例)

当 CPU 从进程 A 切换到进程 B 时:

  1. CPU 硬件自动把当前程序计数器、寄存器等数据压入进程 A 的内核栈;
  2. OS 内核将这些硬件状态保存到进程 A 的 PCB 中;
  3. OS 把进程 A 的状态从 “运行态” 改为 “就绪态”,放回就绪队列;
  4. 从就绪队列中选中进程 B,读取进程 B 的 PCB 信息;
  5. 根据 PCB 中的数据,恢复进程 B 的寄存器、程序计数器等硬件状态;
  6. 进程 B 从上次暂停的位置继续执行,状态变为 “运行态”。

上下文切换存在固有开销:切换期间 CPU 不执行任何用户代码,因此频繁切换会降低系统整体效率。

三、进程调度算法与实例计算

进程调度的任务是从就绪队列中按照既定规则选中一个进程,将 CPU 分配给它。不同算法适用于不同业务场景。

1. 先来先服务(FCFS, First Come First Served)

  • 规则:按进程到达就绪队列的先后顺序调度,先到的先执行。
  • 特点:非抢占式,实现简单;对短作业不友好,平均等待时间长。
  • 实例计算: 三个进程 P1、P2、P3,到达时间均为 0,服务时间分别为 24ms、3ms、3ms。 执行顺序:P1 → P2 → P3
    • P1:等待时间 0,周转时间 24
    • P2:等待时间 24,周转时间 27
    • P3:等待时间 27,周转时间 30
    • 平均周转时间:(24+27+30)/3 = 27ms

2. 短作业优先(SJF, Shortest Job First)

  • 规则:优先调度服务时间最短的进程。
  • 特点:平均等待时间最短,系统吞吐量高;对长作业不友好,可能出现 “饥饿” 现象。
  • 实例计算(同上述进程): 执行顺序:P2 → P3 → P1
    • P2:等待时间 0,周转时间 3
    • P3:等待时间 3,周转时间 6
    • P1:等待时间 6,周转时间 30
    • 平均周转时间:(3+6+30)/3 = 13ms,性能远优于 FCFS。

3. 时间片轮转(RR, Round Robin)

  • 规则:每个进程分配一个固定大小的时间片,时间片用完就强制让出 CPU,回到就绪队列末尾排队。
  • 特点:抢占式,公平性好,响应速度快,适用于分时系统;时间片大小直接影响系统性能。
  • 实例计算: 三个进程 P1、P2、P3,到达时间均为 0,服务时间分别为 5ms、3ms、4ms,时间片为 2ms。 执行序列:P1 (2) → P2 (2) → P3 (2) → P1 (2) → P2 (1) → P3 (2) → P1 (1)
    • P1 周转时间:13ms
    • P2 周转时间:9ms
    • P3 周转时间:12ms
    • 平均周转时间:(13+9+12)/3 ≈ 11.33ms

4. 优先级调度

  • 规则:每个进程分配优先级,优先调度优先级高的进程。
  • 分类:静态优先级(创建时确定,运行中不变)、动态优先级(运行中动态调整,防止长作业饥饿)。
  • 实例:操作系统中,内核进程优先级高于用户进程;实时音视频进程优先级高于后台下载进程。

四、进程同步与互斥

当多个进程共享临界资源(同一时间只能被一个进程使用的资源,如打印机、共享变量)时,需要通过同步互斥机制保证数据一致性。

核心概念

  • 互斥:多个进程不能同时进入临界区(访问临界资源的代码段)。
  • 同步:多个进程需要按照约定的顺序执行,比如生产者生产完成后,消费者才能消费。
  • 信号量(Semaphore):OS 提供的同步互斥工具,本质是一个整数变量,配合 P、V 两个原子操作使用。
    • P 操作:信号量减 1,如果结果 < 0,进程阻塞;
    • V 操作:信号量加 1,如果结果≤0,唤醒一个阻塞的进程。

经典实例:生产者 - 消费者问题

场景:有一个大小为 n 的缓冲区,生产者进程往缓冲区放数据,消费者进程从缓冲区取数据。

  • 缓冲区满时,生产者不能放数据;
  • 缓冲区空时,消费者不能取数据;
  • 同一时间只能有一个进程操作缓冲区。

信号量设置

  • empty = n:空缓冲区数量
  • full = 0:满缓冲区数量
  • mutex = 1:互斥信号量,保护缓冲区

伪代码实现

c

运行

// 生产者进程
while(1) {
    生产数据;
    P(empty);   // 申请空缓冲区
    P(mutex);   // 进入临界区
    把数据放入缓冲区;
    V(mutex);   // 退出临界区
    V(full);    // 满缓冲区数量+1
}

// 消费者进程
while(1) {
    P(full);    // 申请满缓冲区
    P(mutex);   // 进入临界区
    从缓冲区取出数据;
    V(mutex);   // 退出临界区
    V(empty);   // 空缓冲区数量+1
    消费数据;
}

关键说明:P 操作的顺序不能颠倒,必须先执行同步信号量的 P,再执行互斥信号量的 P,否则会触发死锁。

五、进程与线程的核心区别

随着并发需求提升,线程(Thread)被引入,作为CPU 调度的基本单位,进一步降低了并发的系统开销。

核心区别

表格

维度 进程 线程
资源拥有 资源分配的基本单位,拥有独立内存空间和系统资源 不拥有独立资源,共享所属进程的全部资源
调度单位 早期操作系统的调度单位 现代操作系统的 CPU 调度基本单位
切换开销 大,需要切换页表、刷新 TLB、保存完整 PCB 小,只需保存线程上下文,共享进程内存
通信方式 需要通过专门的 IPC 机制,开销大 直接读写进程共享内存,通信便捷
稳定性 一个进程崩溃不影响其他进程 一个线程崩溃,整个进程都会崩溃

实例

Chrome 浏览器采用多进程架构

  • 每个标签页是一个独立的渲染进程,插件、网络、GPU 也各有独立进程;
  • 单个标签页崩溃不会导致整个浏览器闪退,提升了整体稳定性;
  • 每个进程内部又有多个线程,比如渲染主线程、IO 线程、合成线程,分别负责不同的子任务。
谢谢
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐