【操作系统】 管程机制

基本概念

信号量机制中,每个要访问临界资源的进程都必须自备同步的PV操作,大量分散的同步操作会给系统管理带来麻烦,且容易因为同步操作不当而导致系统死锁。于是便产生了一种新的进程同步工具——管程(Monitors)

管程(Monitors):是一个资源管理模块,其中包含了共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程(方法)所组成的资源管理程序。

管程中包含条件变量,用于管理进程的阻塞和唤醒。其形式为 condition x;对它的操作仅有wait和signal。

  x.wait:正在调用管程的进程因 x 条件需要被阻塞或挂起,则调用 x.wait 将自己插入到 x 条件的等待队列上,并释放管程,直到 x 条件变化。此时其它进程可以使用该管程。

   x.signal:正在调用管程的进程发现 x 条件发生了变化,则调用 x.signal,重新启动一个因 x 条件而阻塞或挂起的进程。(与信号量的signal不同,没有s:=s+1的操作)

 

个人理解:

  1. 管程相当于把对临界资源的操作封装了起来,当进程要对资源进行操作时,只要调用管程中的方法就可以了,而不用进程自己担心同步和互斥的问题,管程的内部有自己的一套机制进行同步与互斥。
  2. 管程中每次只允许一个进程进入管程。
  3. 当调用管程的进程因为某原因阻塞或者挂起时,把这个原因定义为一个条件变量x。
  4. x.wait操作就是把自己放到一个队列上,这个队列上的进程都是因为x原因而阻塞的。
  5. x.signal操作就是让在x阻塞队列上的一个进程重新启动。

相对形象的比喻:假如一个管程叫ATM(取款机),其包含两个方法:存款和取款,不同的人代表不同的进程,但是ATM只允许一个人在一个时间段中进行操作,当一个人在使用时,其他的人只能wait。此外,一个人如果使用的时间太长也不行,所以需要一个条件变量来约束他。

比如一个人在操作ATM时突然接电话了,没法继续操作,把这个原因记为x,执行x.wait,让他离开ATM机,去接电话的队列中等待。等到打完电话,即调用了x.signal后,他就可以继续操作ATM了(一般令正在操作ATM的人操作完后,他才能重新进去)。

 

实际应用:

 生产者-消费者问题

建立producer-consumer管程,其中包括两个方法

1.put(x):生产者利用该过程将自己生产的产品投放到缓冲池中,并用整型变量 count 来表示在缓冲池中已有的产品数目,当 count≥n 时,表示缓冲池已满,生产者须等待。

2.get(x):消费者利用该过程从缓冲池中取出一个产品,当 count≤0 时,表示缓冲池中已无可取用的产品,消费者应等待。

两个条件变量:notfull和notempty,代表进程阻塞原因

producer-consumer管程的描述:

type producer-consumer=monitor
    Var in,out,count: integer;
        buffer: array[0, …, n-1] of item;
        notfull,notempty:condition;  //条件变量
        procedure entry put(item)
            begin
               if count>=n then notfull.wait;  //缓冲池已经满了,生产者需要等待(我觉得命名为full可能更好,代表原因;不过也可以理解为:等到notfull才继续执行)
                   buffer(in):=nextp;
                   in:=(in+1) mod n;
                   count:=count+1;
                   if notempty.queue then notempty.signal;  //唤醒一个在notempty队列中等待的进程
            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.quene then notfull.signal;
            end
      begin in:=out:=0;
count:=0
end

 

生产者-消费者的描述:

producer: begin
		repeat
			produce an item in nextp;
			PC.put(item);
		until false;
	   end
consumer: begin
		repeat
			PC.get(item);
			consume the item in nextc;
		until false;
	   end

  

参考资料:《计算机操作系统(第三版)》(汤小丹等著)

 

posted @ 2018-07-11 17:04  华仔要长胖  阅读(6096)  评论(1编辑  收藏  举报