首页/操作系统/02-process/管程机制 🔗 在 Obsidian 中打开
操作系统 · 02-process

管程机制

重要度 ★★★★★ 互斥同步HoareMesa条件变量
速查
管程是高级同步机制,将共享数据 + 操作过程封装在一起、由编译器自动加锁实现互斥;Hoare 语义为"signal = 我让出,你来",Mesa 语义为"signal = 提醒你条件可能成立了"。

速查

项目
核心概念管程机制
关键公式/性质Hoare:signal 即"我让出,你来";Mesa:signal 即"提醒你条件可能成立了"
考试频率⭐⭐⭐⭐

一、基本概念

管程(Monitor)是一种高级同步机制,将共享数据和操作封装在一起,提供互斥访问。由 Brinch Hansen 和 Hoare 提出。

为什么需要管程

  • 信号量使用困难:P/V 操作分散,容易出错
  • 管程将同步操作封装,降低编程复杂度

二、管程的组成

┌─────────────────────────────────────┐
│              管程 (Monitor)          │
│                                     │
│  ┌─────────────────────────────┐   │
│  │   共享数据 (Shared Data)     │   │
│  └─────────────────────────────┘   │
│                                     │
│  ┌─────────────────────────────┐   │
│  │   操作过程 (Procedures)      │   │
│  │   procedure1()              │   │
│  │   procedure2()              │   │
│  └─────────────────────────────┘   │
│                                     │
│  ┌─────────────────────────────┐   │
│  │   初始化代码 (Init Code)     │   │
│  └─────────────────────────────┘   │
│                                     │
│  入口队列: [P1] [P2] [P3] ...      │
│                                     │
│  条件变量:                          │
│    x: [等待队列]                    │
│    y: [等待队列]                    │
└─────────────────────────────────────┘

四个组成部分

  1. 共享数据:管程内部的数据结构
  2. 操作过程:对共享数据的操作函数
  3. 初始化代码:对共享数据的初始化
  4. 条件变量:用于同步的条件等待机制

三、管程的特性

1. 互斥性

  • 任一时刻,最多只有一个进程在管程内执行
  • 编译器自动添加互斥锁(不需要程序员手动加锁)

2. 封装性

  • 共享数据只能通过管程的过程访问
  • 外部无法直接访问管程内部数据

3. 条件等待

  • 进程在管程内可以等待某个条件成立
  • 使用条件变量(condition variable)

四、条件变量操作

wait 操作

x.wait();  // 阻塞当前进程,将其放入条件x的等待队列
           // 同时释放管程的互斥锁

signal 操作

x.signal();  // 唤醒条件x等待队列中的一个进程
             // 被唤醒进程从wait处继续执行

与信号量 P/V 的区别

操作信号量管程条件变量
P/wait若 $S \leq 0$ 则阻塞无条件阻塞(释放管程锁)
V/signalS++,唤醒唤醒一个等待者
注意关键区别:signal 不会阻塞发送者(但若不释放管程,被唤醒者无法执行)。

五、Hoare 管程 vs Mesa 管程

Hoare 管程

  • signal 后,发送者立即让出管程
  • 被唤醒者立即执行
  • 语义:signal = "我让出,你来"
P1执行signal → P1离开管程
               P2被唤醒 → 立即进入管程执行
               P2完成后 → P1重新进入管程

Mesa 管程

  • signal 后,发送者继续执行
  • 被唤醒者需要重新竞争管程锁
  • 语义:signal = "提醒你条件可能成立了"
  • 被唤醒后条件可能已变,需用 while 循环重新检查
while (!condition) {
    x.wait();  // Mesa风格:必须用while重新检查
}

对比

特性HoareMesa
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();

七、管程与信号量的等价性

管程和信号量在表达能力上是等价的,可以互相模拟。

用信号量实现管程

  • 用一个互斥信号量实现管程入口互斥
  • 用信号量模拟条件变量的 wait/signal

用管程实现信号量

monitor Semaphore {
    int value;
    condition cv;

    procedure P() {
        if (value == 0) cv.wait();
        value--;
    }

    procedure V() {
        value++;
        cv.signal();
    }
}

八、管程的优缺点

优点

  1. 封装性好,隐藏同步细节
  2. 减少程序员犯错机会
  3. 易于验证正确性
  4. 代码更清晰可读

缺点

  1. 依赖编译器支持
  2. 管程内不能做阻塞 I/O
  3. 不如信号量灵活

九、实际系统中的管程

  • Java synchronized:类似 Mesa 管程
  • Pascal Concurrent Pascal:Brinch Hansen 实现
  • Python threading.Condition:条件变量实现

Java 示例

class Monitor {
    private int sharedData;

    public synchronized void method1() {
        while (条件不满足) wait();
        // 操作共享数据
        notify();  // signal
    }
}

记忆卡片

管程的四个组成部分?
共享数据、操作过程、初始化代码、条件变量。
Hoare 与 Mesa 的 signal 区别?
Hoare:发送者让出管程,被唤醒者立即执行;Mesa:发送者继续,被唤醒者需重新竞争且用 while 重查。
Mesa 为何用 while 而非 if?
signal 后发送者继续,到被唤醒者执行时条件可能已变,需循环重新验证。
条件变量 wait 与信号量 P 的区别?
wait 无条件阻塞(释放管程锁后等待);P 是条件阻塞(仅当 $S \leq 0$ 时阻塞)。

交互动画 · Hoare vs Mesa 信号

P1(发送者) P2(等待者) 在管程内 等待条件 signal 唤醒 P2 P2 进入管程 P1 继续执行
点击「Hoare 语义」或「Mesa 语义」查看 signal 后的不同流向
橙色=发送者→等待者;绿色=等待者进入管程
Hoare:signal 后 P1 立刻让出管程,P2 立即进入执行;Mesa:signal 后 P1 继续执行,P2 需重新竞争锁后方可进入。

相关知识点

process-synchronization-semaphore deadlock dining-philosophers producer-consumer readers-writers

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。