形式陈述 ​
管程(monitor)是带并发访问纪律的抽象数据类型。它把共享表示状态
线程进入公开过程时自动取得管程所有权,正常返回时释放。若在条件变量 wait(c),调用者原子地加入
signal(c) 的控制转移有两种经典语义,不能混用。
- Hoare 语义(signal-and-urgent-wait):若
上有等待者,signal 立即把管程交给其中一个等待线程;signal 线程进入 urgent queue,待被唤醒线程离开管程或再次等待后才恢复。因此 signal 时刚建立的谓词可以直接交给等待者,但实现必须管理这次即时所有权移交。 - Mesa 语义(signal-and-continue):signal 线程继续在管程内执行,被通知线程只是进入可运行状态;它要等 signal 线程退出并重新竞争管程,才会从 wait 返回。其间共享状态可能再次变化,运行库还可能允许虚假唤醒,所以等待者必须在循环中重新检查谓词。
现代语言与线程库通常采用 Mesa 风格,标准形态是 while not P(s): wait(c)。通知只表示“某次状态变化可能使谓词成立”,不承诺被唤醒线程立即运行,也不承诺它取得管程时谓词仍为真。entry queue、condition queue 和 Hoare 语义中的 urgent queue 如何选择线程,属于调度策略;基本管程定义不自动提供 FIFO、无饥饿或优先级保证。
管程的互斥保证还依赖封装边界。若过程返回指向内部可变数组的引用,或另一个模块仍持有状态别名,外部代码便可绕开入口锁修改表示,
直觉 ​
mutex 给程序一把需要手工获取和释放的钥匙,条件变量提供“条件尚未满足时交出钥匙并等待”的动作;管程把钥匙、等待室和被保护的数据一起藏进模块。调用者只看见 put、get 之类操作,不需要在每个调用点重复同一套加锁顺序。
封装使同步规则靠近表示不变量。队列长度、头尾索引和元素数组由同一入口互斥保护,条件谓词也直接写成这些字段上的判断。这样可以局部证明“每个过程从满足
例子与边界 ​
容量为
它有两个条件队列 not_empty 与 not_full,公开过程可写成:
put(x):
while |Q| = C:
wait(not_full)
enqueue(Q, x)
signal(not_empty)
get():
while |Q| = 0:
wait(not_empty)
x := dequeue(Q)
signal(not_full)
return x
入口互斥使容量检查与队列修改相对于其他管程过程不可交错;wait 则在缓冲区满或空时释放管程,让能够改变条件的消费者或生产者进入。Mesa 语义下必须使用 while:消费者被通知后,另一个消费者可能先取得管程并拿走唯一元素;重新检查把共享状态恢复为操作前提。
若某个管程过程在持有入口所有权时调用慢速网络服务、等待一个必须由另一管程过程完成的 future,或者执行任意不释放管程的外部阻塞,其他调用者都会被挡在入口。条件变量的 wait 会按协议释放管程,普通阻塞调用不会;“过程内部可以等待”不能被理解为所有等待都安全。
嵌套管程也可能死锁。线程 A 在管程
推论与应用 ​
管程、mutex、条件变量和信号量位于不同抽象层。mutex 是具有所有权的同步对象;条件变量让线程等待受锁谓词;管程把二者与共享表示封装成模块。信号量则保存可用许可数量,signal 会增加可消费状态,即使当时没有等待者;管程条件通知通常不持久,事实来源始终是表示谓词。
管程尤其适合把对象不变量和同步策略一起审查,但它不保证所有调用都快速或最终完成。外泄引用会绕开保护,嵌套调用会引入锁序,Mesa 通知可能造成争抢,不公平调度还可让某个入口或条件等待者长期得不到服务。完整规格仍需单独声明异常安全、可重入性、调度公平和外部调用规则。
它之所以是可选节点,是因为核心语义可以由 mutex、条件变量和抽象数据类型组合表达;独立页面的价值在于给这组组合增加明确的模块封装边界,以及 Hoare/Mesa 控制转移的统一定位,而不是引入另一套底层同步能力。
参考资料
- C. A. R. Hoare, “Monitors: An Operating System Structuring Concept,” Communications of the ACM 17(10), 1974, pp. 549–557。
- Butler W. Lampson and David D. Redell, “Experience with Processes and Monitors in Mesa,” Communications of the ACM 23(2), 1980, pp. 105–117。
- Per Brinch Hansen, Operating System Principles, Prentice-Hall, 1973,monitor and process synchronization chapters。