管程是允许线程具有互斥、等待(堵塞)某个条件为false的能力的同步结构。具有通知其他线程他们特定条件已经满足的机制。管程为线程提供了可以暂时放弃独占访问,以便在重新获得独占访问并恢复任务之前等待满足某些条件。
管程有互斥锁以及特定条件变量组成。条件变量本质上是等待特定条件的线程的容器
互斥:同一时刻只允许一个线程访问共享资源
同步:线程之间通信、协作
// thread 1
synchronized(someObject) {
// do something x
}
// thread 2
synchronized(someObject) {
// do something y
}
// 在Java中的管程会控制仅有一个线程在临界区中执行,并且没有显性的wait、notify
条件变量
条件变量是等待特定条件发生的同步原语,用于维护等待队列,也有wait()、signal(),只是不能累积数量
wait(c)
:调用进程被阻塞并移入与条件变量c相关的队列中,并释放管程,直到另一个进程在该条件变量c上执行signal(c)
唤醒等待进程并将其移出c的队列。signal(c)
:如果存在其他进程由于执行wait(c)
而被阻塞,便释放一个;如果没有进程在等待,那么信号被丢弃而不会产生任何效果。
优缺点
优点:
- 相比于信号量更容易实现
- 监控器可以克服使用信号量时出现的时序错误。比如生产者消费者中,在生产者还没有堵塞之前就给生产者发送了释放信号
缺点:
- 必须被编程语言实现
- 给了编译器额外负担去了解操作系统哪些特性可用来控制并发进程中临界区的访问
与信号量的不同
- 信号量是整型变量,允许多个进程管理对公共资源的访问;而管程则是同步技术,允许线程相互排斥,并wait()特定条件为true
- 当进程对共享资源使用信号量时,调用wait()方法堵塞资源,调用signal()释放资源;管程则是通过管程结构在进程中访问
- 信号量是整数,管程则是抽象数据结构
- 信号量的整数表明了可用资源数量,而管程则是一个在同一时间只允许一个进程在临界区执行的抽象数据结构
- 信号量没有条件变量的概念,管程有条件变量
总结来说,管程是将信号量分散的wait、notify封装起来,更利于编程。
管程是一个模型,与信号量并非不相交,实际上在很多语言管程实现中,互斥部分是通过信号量来实现的
Ref
- https://en.wikipedia.org/wiki/Monitor_(synchronization)
- https://www.cnblogs.com/binarylei/p/12544002.html
- https://www.javatpoint.com/semaphore-vs-monitor#:~:text=are%20as%20follows%3A-,A%20semaphore%20is%20an%20integer%20variable%20that%20allows%20many%20processes,given%20condition%20to%20become%20true.