信号量机制的不足:信号量的控制分布在多个进程中
正确性分析困难;
分散的P、V操作:易出错,使用不当可能导致死锁。
修改、维护困难:易读性差,任一修改都可能影响全局;测试期间发现错误困难,即使发现错误也不容易定位出错位置。
主要内容
管程的组成
管程的特点
管程的同步控制(条件变量)
类比生产者—消费者问题
多进程需访问的变量:
buffer,in,out;
empty,full;
对变量做的操作:
向buffer放/取产品,移动指针in,out;
控制放或取的信号量操作wait、signal;
管程的组成
语法:名为monitor_name的管程
Type monitor_name= monitor
variable declarations;
procedure entry P1(){…}
procedure entry P2(){…}
procedure entry Pn(){…}
initialization code;
1.一组局部变量
2.对局部变量操作的一组过程
3.对局部变量进行初始化的语句。
(联想面向对象中的类)
生产者—消费者问题中对缓冲区定义一个管程
type p_c=monitor
var in,out,count: interger;
buffer: array[0,…,n-1] of item
notfull,notempty: condition;
—— —— —— —— —— —— —— —— ——
procedure entry put(var product:item)
{}
procedure entry get(var product:item)
{}
—— —— —— —— —— —— —— —— ——
{ in=out=0;
count=0; }
2.管程特点
任何进程只能通过调用管程提供的过程入口才能进入管程访问共享数据;
就如同使用临界资源,就要先通过其信号量的申请。
任何时刻,仅允许一个进程在管程中执行某个内部过程。
3.条件变量
(主要作用就是进程同步的阻塞和唤醒控制)
局部于管程的变量有两种:
普通变量
条件变量(用于控制进程阻塞和唤醒)
类似信号量变量,但不取具体值;相当于每个阻塞队列的队列指针。
对条件变量的操作需结合对普通变量的条件判断,从而控制进程状态。
管程的优点
保证进程互斥地访问共享变量,并方便地阻塞和唤醒进程。管程可以以函数库的形式实现。相比之下,管程比信号量好控制。
管程可增强模块的独立性:系统按资源管理的观点分解成若干模块,用数据表示抽象系统资源,使同步操作相对集中,从而增加了模块的相对独立性
引入管程可提高代码的可读性,便于修改和维护,正确性易于保证:采用集中式同步机制。一个操作系统或并发程序由若干个这样的模块所构成,一个模块通常较短,模块之间关系清晰。
管程的缺点
大多数常用的编程语言中没有实现管程,如果某种语言本身不支持管程,那么加入管程是很困难的。
虽然大多数编程语言也没有实现信号量,但可将P、V操作作为一个独立的子例程或操作系统的管理程序调用加入。