题目
以下是利用管程(其名为producer-consumer)来解决生产者与消费者的程序,试给每一行代码加上注释(除begin、end这样的边界标识之外)。
答案
代码
type producer-consumer=monitor; //管程名称
Var in,out,count:integer; //读写指针(放产品取产品)以及已放置于缓冲区的产品数量
buffer:array[0,…,n-1]of item; //代表缓冲区的数组, item是产品的类型
nofull, noempty:condition; //代表生产者等待放产品队列和消费者等待取产品队列
/*
生产者利用该过程将自己生产的产品放到缓冲池,用整型变量count 表示在缓冲池中已有的产品数目,当count==n 时,表示缓冲池已满(无空栅格),生产者须等待;当生产者放置产品后,count==1时,表示缓冲池刚才是空的(那么有可能存在等待的消费者取产品),则唤醒等待的消费者(如果有等待的消费者,则唤醒等待队列中第一个消费者;若没有等待的消费者,则空操作)
*/
procedure entry put(nextp:item)
begin
if count==n then wait(noempty); //无空栅格,生产者阻塞自己
buffer(in):=nextp;
in:=(in+1)mod n;
count:=count+1;
if count==1 then.signal(nofull); //有等待的消费者,则唤醒等待队列中第一个消费者
end
/*
消费者利用该过程从缓冲池中取出一个产品,当count==0时,表示缓冲池中已无可取的产品(无满栅格),消费者应等待;当消费者取走一件产品后,count==n-1时,表示缓冲池刚才是满的(那么有可能存在等待的生产者放产品),则唤醒等待的生产者(如果有等待的生产者,则唤醒等待队列中第一个生产者;若没有等待的生产者,则空操作)
*/
procedure entry get(nextc:item)
begin
if count==0 then wait(nofull); //无满栅格,生产者消费自己
nextc:=buffer(out);
out:=(out+1)mod n;
count:=count-1;
if count==n-1 then signal(noempty); //有等待的生产者,则唤醒等待队列中第一个生产者
end
begin
in:=out:=0; //设置初始值
count:=0;
end
生产者进程的描述:
producer: begin
pepeat
produce an item in nextp; //生产一件item类型的产品nextp
PC.put(nextp); //放置到缓冲区的一个栅格中
until false;
end
消费者进程的描述:
consumer: begin
repeat
PC.get(nextc); //从缓冲区的一个栅格中取出一件产品
consume the item in nextc; //消费这件产品
until false;
end