Appearance
408
操作系统
条件变量与管程
一、定位信息
- 所属圈层:核心层
- 前置知识:掌握信号量机制(OS-02-11),了解互斥与同步的概念(OS-02-09)
- 知识网络位置:管程是比信号量更高级的同步工具,用于替代信号量解决同步问题,避免P/V操作分散在各处导致的错误
- 考点热度等级:M级(中频常考)——近5年选择题出现约2–3次,主要考查管程的概念和条件变量
二、知识点讲解
2.1 管程的定义与动机
动机:信号量的P/V操作分散在各进程中,容易出现错误(如P/V不配对、顺序错误)。**管程(Monitor)**将共享数据和操作封装在一起,提供更高层次的同步抽象。
定义:管程是一种高级同步机制,由以下部分组成:
- 共享数据:管程内的共享变量
- 操作过程:对共享数据的操作函数
- 初始化代码:对共享数据的初始化
- 互斥特性:同一时刻只有一个进程可以在管程内执行
2.2 管程的特性
| 特性 | 说明 |
|---|---|
| 互斥性 | 任何时候最多一个进程在管程内执行 |
| 封装性 | 共享数据只能通过管程的过程访问 |
| 条件等待 | 通过条件变量实现进程的等待和唤醒 |
2.3 条件变量(Condition Variable)
管程内的进程可能需要等待某个条件成立才能继续执行。条件变量是管程内用于实现条件等待的工具。
c
monitor ProducerConsumer {
condition notFull, notEmpty; // 条件变量
int count = 0; // 缓冲区中的数据量
void produce(item) {
if (count == N)
notFull.wait(); // 缓冲区满,等待
put item into buffer;
count++;
notEmpty.signal(); // 通知消费者
}
item consume() {
if (count == 0)
notEmpty.wait(); // 缓冲区空,等待
remove item from buffer;
count--;
notFull.signal(); // 通知生产者
return item;
}
}2.4 条件变量的两个操作
| 操作 | 含义 | 类比信号量 |
|---|---|---|
x.wait() | 在条件x上阻塞,释放管程的互斥锁 | 类似P操作 |
x.signal() | 唤醒在条件x上等待的一个进程 | 类似V操作 |
2.5 管程 vs 信号量对比表
| 维度 | 信号量 | 管程 |
|---|---|---|
| 抽象层次 | 低级同步工具 | 高级同步工具 |
| 封装性 | 差(P/V分散在各进程) | 好(封装在管程内) |
| 易用性 | 容易出错(P/V不配对等) | 不易出错(结构化) |
| 实现基础 | 可独立实现 | 通常基于信号量或互斥锁实现 |
| 条件等待 | 通过信号量值间接实现 | 通过条件变量直接实现 |
| 编程模型 | 分散式(各处P/V) | 集中式(管程内管理) |
| 典型语言支持 | C(手动实现) | Java(synchronized)、Pascal |
三、记忆与理解辅助
- 管程一句话:管程=共享数据+操作过程+互斥保护+条件变量,是"面向对象的同步机制"
- 条件变量vs信号量:条件变量只用于管程内,信号量可用于任何地方;条件变量的
signal只唤醒一个等待进程,信号量的V操作可能唤醒多个 - 管程的互斥性:由编译器自动保证,程序员不需要手动P/V互斥信号量
- Hoare vs Hansen管程:Hoare管程中signal后立即切换到被唤醒进程,Hansen管程中signal后当前进程继续执行直到退出管程
四、例题与精解
例题1(基础巩固)
题目:以下关于管程的描述,正确的是( )
A. 管程中的共享数据可以被任何进程直接访问 B. 管程中同一时刻可以有多个进程同时执行 C. 管程通过条件变量实现进程的同步等待 D. 管程不能实现互斥功能
命题意图:考查管程的基本特性。
精解:
- 审题分析:逐项判断管程的特性
- 解题思路:管程的核心特性——互斥性、封装性、条件等待
- 完整步骤:
- A选项:错误。管程的共享数据被封装,只能通过管程内的过程访问(封装性)
- B选项:错误。管程保证同一时刻只有一个进程在内执行(互斥性)
- C选项:正确。管程通过条件变量(condition variable)实现进程的条件等待和唤醒
- D选项:错误。互斥性是管程的基本特性之一
- 方法反思:管程的三大特性——互斥、封装、条件等待,缺一不可
答案:C
例题2(中等提升)
题目:在管程中执行 x.signal() 操作后,以下说法正确的是( )
A. 执行signal的进程立即退出管程 B. 被唤醒的进程立即开始执行管程代码 C. 在Hoare管程中,执行signal的进程释放管程互斥锁,被唤醒进程获得锁后执行 D. signal操作可以唤醒所有在条件x上等待的进程
命题意图:考查条件变量signal操作的行为。
精解:
- 审题分析:需要理解signal操作后的进程调度行为
- 解题思路:区分Hoare管程和Hansen管程中signal的不同行为
- 完整步骤:
- A选项:不完全正确。在Hoare管程中,执行signal后当前进程被阻塞(不是退出),在Hansen管程中当前进程继续执行直到退出
- B选项:不完全正确。被唤醒进程何时执行取决于管程类型
- C选项:正确。在Hoare管程中,signal释放管程互斥锁给被唤醒进程,当前进程被阻塞直到被唤醒进程退出管程
- D选项:错误。signal只唤醒一个等待进程,不是所有
- 方法反思:Hoare管程"signal即切换",Hansen管程"signal后继续"
答案:C
五、考情分析
- 考查频次:近5年约2–3次
- 常见题型:选择题
- 分值占比:2分/题
- 命题趋势:管程的基本概念和条件变量的操作是主要考点,可能与信号量对比出题
六、易错点提醒
错误表现:认为管程中的条件变量和信号量完全相同 错误原因:两者都有wait/signal操作 正确理解:条件变量的signal不累积(没有"值"的概念),信号量的V操作有累积效果
错误表现:认为管程内可以有多个进程同时执行 错误原因:忽略了管程的互斥性 正确理解:管程保证同一时刻最多一个进程在内执行,互斥由编译器自动保证
错误表现:混淆Hoare管程和Hansen管程的signal行为 错误原因:两种管程的signal操作后行为不同 正确理解:Hoare管程中signal后当前进程阻塞、被唤醒进程执行;Hansen管程中signal后当前进程继续执行
错误表现:认为管程不能解决生产者-消费者问题 错误原因:不了解管程的实际应用 正确理解:管程可以通过条件变量轻松实现生产者-消费者同步,且代码更清晰
七、来源标注
- 依据2026考研统考408大纲
- 依据《计算机操作系统》(汤小丹/汤子瀛版)第2章
- 依据《操作系统概念》(Silberschatz版)第6章