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