问题描述:
一个数据文件或记录,可被多个进程共享,我们把只要求读该文件的进程称为“Reader 进程”,其他进程则称为“Writer 进程” 。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个 Writer 进程和其他 Reader 进程或 Writer 进程同时访问共享对象,因为这种访问将会引起混乱。所谓“读者—写者问题(Reader-Writer Problem)”是 指保证一个 Writer 进程必须与其他进程互斥地访问共享对象的同步问题。读者—写者问题 常被用来测试新同步原语。
1. 利用记录型信号量解决读者—写者问题
为实现 Reader 与 Writer 进程间在读或写时的互斥而设置了一个互斥信号量 Wmutex。 另外,再设置一个整型变量 Readcount 表示正在读的进程数目。由于只要有一个 Reader 进程在读,便不允许 Writer 进程去写。因此,仅当 Readcount=0,表示尚无 Reader 进程在读时,Reader 进程才需要执行 Wait(Wmutex)操作。若 Wait(Wmutex)操作成功,Reader 进程便可去读,相应地,做 Readcount+1 操作。同理,仅当 Reader 进程在执行了 Readcount 减 1 操作后其值为 0 时,才须执行 signal(Wmutex)操作,以便让 Writer 进程写。又因为 Readcount 是一个可被多个 Reader 进程访问的临界资源,因此,也应该为它设置一个互斥信号量 rmutex。
解释:
互斥信号量wmutex: 实现Reader与Writer进程间在读或写时的互斥,整型变量Readcount: 表示正在读的进程数目;由于只要有一个Reader进程在读,便不允许Writer进程写。所以,仅当Readcount=0,即无Reader进程在读时,Reader才需要执行Wait(wmutex)操作。若Wait(wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1操作。同理,仅当Reader进程在执行了Readcount减1操作后其值为0时,才需执行signal(wmutex)操作,以便让Write进程写
互斥信号量rmutex: Reader进程间互斥访问Readcount
读者—写者问题可描述如下:
1 Var rmutex,wmutex: semaphore:=1,1; 2 Readcount: integer:=0; 3 begin 4 parbegin 5 Reader: begin 6 repeat 7 wait(rmutex); 8 if readcount=0 then wait(wmutex); 9 Readcount:=Readcount+1;10 signal(rmutex);11 ...12 perform read operation;13 ...14 wait(rmutex);15 readcount:=readcount-1;16 if readcount=0 then signal(wmutex);17 signal(rmutex);18 until false;19 end20 writer: begin21 repeat22 wait(wmutex);23 perform write operation;24 signal(wmutex);25 until false;26 end27 parend28 end
2.利用信号量集机制解决读者—写者问题
这里的读者—写者问题与前面的略有不同,它增加了一个限制,即 最 多 只 允许 RN 个读 者同时读。为此,又引入了一个信号量 L,并赋予其初值为 RN,通过执行 wait(L,1,1) 操作,来控制读者的数目。每当有一个读者进入时,就要先执行 wait(L,1,1)操作,使 L 的值减 1。当有 RN 个读者进入读后,L 便减为 0,第 RN+1 个读者要进入读时,必然会因 wait(L,1,1)操作失败而阻塞。
描述如下:
1 Var RN integer; 2 L, mx: semaphore:=RN,1; 3 begin 4 parbegin 5 reader: begin 6 repeat 7 Swait(L,1,1); 8 Swait(mx,1,0); 9 ...10 perform read operation; 11 ...12 Ssignal(L,1);13 until false;14 end15 writer: begin16 repeat17 Swait(mx,1,1;L,RN,0);18 perform write operation;19 Ssignal(mx,1);20 until false;21 end22 parend23 end