应用题 31.有一阅览室,读者进入时必须先在一张登记表上登记,该表为每一座位列出一个表目,包括座号、姓名,读者离开时要注销登记信息;假如阅览室共有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;
cobegm
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);
离开阅览室:
}
eoend
(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=l to 100 d0 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 j=1 to 100 do i++
if name[i]==readername then name[i]:=null;
release(IM);
end
begin
seatcount:=100;name:=null;
end
cobegin
process readeri(i=l,2.…)
begin
readercome(readername);
read the book;
readerleave(readername);
leave the readroom:
end
coend
【答案解析】