操作系统 管程

在前面 进程 中提到,有信号量与互斥量之后,似乎进程间通信就很容易了。但事实上并不然,PV操作不慎是很容易导致两个进程都被阻塞的,这种情况就叫做死锁(Dead Lock)

为了更容易编写出正确的程序,1973和1974年Hansen与Hoare提出了另一种高级同步原语,称为管程(Monitor)

但他们提出的方式略微有些差别,不过核心都是资源集中管理,将系统中资源通过抽象的形式描述。

管程是一个由过程、变量、数据结构等组成的集合,它们共同形成一个模块或是软件包。进程可以在任何需要的时候调用管程中的过程,但不能在管程声明之外的过程中访问管程内的数据结构。

还提供了一种 条件结构(Condition Construct) 的机制来保障多进程安全、有效的共享数据。如为实现进程互斥同步,可以定义一些条件变量,这些条件变量只能被wait或者signal操作访问。前者表示调用该操作的进程将挂起,而后者是启动一个被挂起的进程,但与V操作不同的是后者不会改变条件变量的状态,如果失败则等于空操作。

假定要仍然用来解决生产者与消费者问题,则可以定义notfull, notempty的条件变量,类语言过程如下:

Type Producer-Consumer=monitor
		var buffer : array[0,...,n-1] of item;
		in, out, count : interger;
		notfull, notempty : condition; //定义条件变量
	procedure entry put(item) //将产品放入缓冲区
	  begin
	  	if count >= n then notfull.wait; //缓冲区满则等待
	  	buffer(in):=nextp;
	  	in:=(in+1) mod n;
	  	count:=count+1;
	  	if notempty.queue then notempty.signal; //唤醒等待者
	  end
	procedure entry get(item)
	  begin
	  	if count <= 0 then notempty.wait; //缓冲区空等待
	  	nextc:=buffer(out);
	  	out:=(out+1) mod n;
	  	count:=count+1;
	  	if notfull.queue then notfull.signal //唤醒生产者
	  end
    
    begin in:=out:=0; count:=0; end //初始化
    cobegin
    	producer : begin
    		repeat
    		produce an item in nextp;
    		Producer-Consumer.put(item);
    		until false;
    	end
    	
    	consumer:begin
    		repeat
    		Producer-Consumer.get(item);
    		consume the item in nextc;
    		until false;
    	end
    coend	

其实管程概念实际上是一种将互斥或信号包装的做法,对管程的支持基本都由编程语言及编译器实现,这样一来就可以减少人为失误导致的死锁,也使的编写大大简便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值