S78用来制约M8的运行。
各进程的制约关系描述如下。
S12,S13,S14,S26,S36,S47,S57,S38,S78:semaphore;
S12:=0;S13:=0;S14:=0;S26:=0;S36:=0;S47:=0;S57:=0;S38:=0;S78:=0; COBEGIN
PROCESS M1: PROCESS M2: BEGIN BEGIN V(S12); P(S12); V(S13); V(S26); V(S14); END END
PROCESS M3: PROCESS M4: BEGIN BEGIN P(S13); P(S14); V(S36); V(S47); V(S38); END END
PROCESS M5: PROCESS M6: BEGIN BEGIN V(S57); P(S26); END P(S36); END
PROCESS M7: PROCESS M8 BEGIN BEGIN P(S47); P(S38); P(S57); P(S78); V(S78); END END COEND
3-16. 叉子是临界资源,在一段时间内只允许一个哲学家使用。一个信号量表示一把叉子,五个信号量构成信号量数组,这些信号量的初值为1。
int fork[0]=fork[1]=…=fork[4]=1; 第i个哲学家所执行的程序: do{ P(mutex); P(fork[i]);
6
P(fork[(i+1)mod5]); V(mutex); 吃饭
V(fork[i]);
V(fork[(i+1)mod5]); } while(1);
3-17.
(1)公平竞争(无写者时,读者仍遵循多个读者可以同时读) rmutex互斥共享readcount; rwmutex读写互斥,写写互斥; 读写进程在z上排队。
int rmutex=1,rwmutex=1,readcount=0;
reader:
begin
p(z); //读写进程在z上排队。 p(rmutex);
if(readcount=0) then p(rwmutex); end if
++readcount; v(rmutex);
v(z); //无写者时,多个读者可以同时读. read data; p(rmutex); 写 --readcount;
if(readcount=0 then v(rwmutex);
end if;
z 读 v(rmutex); 写 … 写 end
读 writer:
读 读 begin
写 p(z); //读写进程在z上排队。 p(rwmutex); write data;
7
v(rwmutex); v(z); … end
(2)写者优先
int readcount,writecount;
semaphore rmutex=1,wmutex=1,rwmutex=1,z=1,x=1;
reader:
//当来了一个写进程时,通过p(x)禁止其后读进程读,直到写进程写完为止。
while(1){
p(z); //其他读进程在z上排队
p(x); //一个读进程与一个写进程在x上竞争 p(rmutex); //读进程互斥访问readcount ++readcount;
if(readcount==1) p(rwmutex); v(rmutex); v(x); v(z); 写 read data; //临界区
p(rmutex); --readcount;
if(readcount==0) v(rwmutex); v(rmutex); }
x z 读 读 读 读 读 rwmutex 写 写 Writer:
while(1){
p(wmutex); //写进程互斥访问writecount ++writecount;
if(writecount==1) p(x); //一个写进程与一个读进程在x上竞争
8
v(wmutex);
p(rwmutex); //其他写进程在rwmutex上排队
write data; //临界区
v(rwmutex); p(wmutex); --writecount;
if(writecount==0) v(x); //写进程都写完时,通过v(x)允许读进程读 v(wmutex); }
附加题:
读者优先,规定仅允许5个进程同时读,怎样修改程序?
解:增加一个资源信号量s,初值为5。 int s=5;
Reader:
begin P(rmutex); readcount=readcount+1; if(readcount==1)then P(rwmutex); V(rmutex); P(s); read_file(); V(s); P(rmutex); readcount=readcount-1; if(readcount==0)then V(rwmutex); V(rmutex); end
writer:
9
begin
p(rwmutex); write data; v(rwmutex); … end
3-18.
int s1=0, s2=n; 顾客进程:
P(s2);
V(s1); 坐椅子等理发
理发师进程:
P(s1); 给顾客理发 V(s2)
读写管程
两个计数器rc和wc分别对读进程和写进程计数,用R和W分别表示允许读和允许写的条件变量,于是管理该文件的管程可如下设计:
type read-writer = MONITOR var rc, wc : integer; R, W : condition;
10