題目
以下是利用管程(其名爲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