经典进程的同步问题之——读者写者

问题描述:

一个数据文件或记录,可被多个进程共享,我们把只要求读该文件的进程称为“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+110             signal(rmutex);
11             ...
12             perform read operation;
13             ...
14             wait(rmutex);
15             readcount:=readcount-116             if readcount=0 then signal(wmutex);
17             signal(rmutex);
18         until false19         end
20         writer:  begin
21             repeat
22                 wait(wmutex);
23                 perform write operation;
24                 signal(wmutex);
25             until false26             end
27     parend
28 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 false14         end
15       writer: begin
16         repeat
17         Swait(mx,1,1;L,RN,0);
18         perform write operation;
19         Ssignal(mx,1);
20         until false21         end
22     parend
23   end

猜你喜欢

转载自www.cnblogs.com/IamJiangXiaoKun/p/9467420.html