应用题 2.有一阅览室,读者进入时必须先在一张登记表上登记,该表为每一座位列出一个表目,包括座号、姓名,读者离开时要注销登记信息;假如阅览室共有100个座位。试分别用信号量和P、V操作以及管程来实现用户进程的同步算法。
【正确答案】(1)使用信号量和P、V操作:
var A:array[1..100]of Rec;
Rec=record
number:integer;
name:string;
end;
i:integer;
for i:=1 to 100 do{A[i].number:=i;A[i].name:=null;}
mutex,seatcount:semaphore: //semaphore:信号量
mutex:=1;seatcount:=100;
cobegin
process readeri(var readername:string)(i=1,2,…){
P(seatcount);
P(mutex);
for i:=1 to 100 do{
i++.
if A[i].name==null then A[i].name:=readername; //读者登记
}
/*必须采用这种方式,因为该空位是随机产生的。我们无法知道哪个读者何时离开*/
V(mutex)
进入阅览室,座号i,坐下读书;
P(mutex); //读书完毕,需要退场
A[i]name:=null;
V(mutex):
V(seatcount);
离开阅览室:
}
coend
(2)使用管程操作:
TYPE readbook=monitor
VAR R:condition;
i,seatcount:integer;
name:array[1..100] of string;
DEFINE readercome,readerleave;
USE check,wait,signal,release:
procedure readercome(readername)
begin
check(IM):
if seatcount≥100 wait(R,IM)
seatcount:=seatcount+1:
for i=1 to 100 do i++
if name[i]==null then name[i]:=readername;
get the seat number=i;
release(IM);
end
procedure readerleave(readername)
begin
check(IM);
seatcount-一;
for i=1 to 100 do i++
if name[i]==reademame then name[i]:=null;
release(IM);
end
begin
seatcount:=100;name:=null:
end
cobegm
process readeri(i=1,2.…)
begin
readercome(readername) :
read the book.
readerleave(readername):
leave the readroom
end
coend
【答案解析】