| 项目 | 值 |
|---|---|
| 核心概念 | 管程机制 |
| 关键公式/性质 | Hoare:signal 即"我让出,你来";Mesa:signal 即"提醒你条件可能成立了" |
| 考试频率 | ⭐⭐⭐⭐ |
管程(Monitor)是一种高级同步机制,将共享数据和操作封装在一起,提供互斥访问。由 Brinch Hansen 和 Hoare 提出。
┌─────────────────────────────────────┐
│ 管程 (Monitor) │
│ │
│ ┌─────────────────────────────┐ │
│ │ 共享数据 (Shared Data) │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ 操作过程 (Procedures) │ │
│ │ procedure1() │ │
│ │ procedure2() │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ 初始化代码 (Init Code) │ │
│ └─────────────────────────────┘ │
│ │
│ 入口队列: [P1] [P2] [P3] ... │
│ │
│ 条件变量: │
│ x: [等待队列] │
│ y: [等待队列] │
└─────────────────────────────────────┘
x.wait(); // 阻塞当前进程,将其放入条件x的等待队列
// 同时释放管程的互斥锁
x.signal(); // 唤醒条件x等待队列中的一个进程
// 被唤醒进程从wait处继续执行
| 操作 | 信号量 | 管程条件变量 |
|---|---|---|
| P/wait | 若 $S \leq 0$ 则阻塞 | 无条件阻塞(释放管程锁) |
| V/signal | S++,唤醒 | 唤醒一个等待者 |
P1执行signal → P1离开管程
P2被唤醒 → 立即进入管程执行
P2完成后 → P1重新进入管程
while (!condition) {
x.wait(); // Mesa风格:必须用while重新检查
}
| 特性 | Hoare | Mesa |
|---|---|---|
| signal 后执行者 | 被唤醒者 | 发送者继续 |
| 条件检查 | 用 if 即可 | 必须用 while |
| 实现复杂度 | 高 | 低 |
| 使用广泛性 | 教学为主 | 实际系统常用 |
monitor ProducerConsumer {
condition notFull, notEmpty;
int buffer[N];
int count = 0;
procedure produce(item) {
if (count == N)
notFull.wait(); // 缓冲区满,等待
buffer[count++] = item;
notEmpty.signal(); // 通知消费者
}
procedure consume() returns item {
if (count == 0)
notEmpty.wait(); // 缓冲区空,等待
item = buffer[--count];
notFull.signal(); // 通知生产者
return item;
}
}
// 生产者进程
ProducerConsumer.produce(item);
// 消费者进程
item = ProducerConsumer.consume();
管程和信号量在表达能力上是等价的,可以互相模拟。
monitor Semaphore {
int value;
condition cv;
procedure P() {
if (value == 0) cv.wait();
value--;
}
procedure V() {
value++;
cv.signal();
}
}
class Monitor {
private int sharedData;
public synchronized void method1() {
while (条件不满足) wait();
// 操作共享数据
notify(); // signal
}
}
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。