操作系统笔记——读者写者问题

4,675 阅读7分钟

一、读者-写者问题: 读者优先

1.问题描述

有两组并发进程:读者和写者,共享一个文件F,要求:
(1)允许多个读者同时执行读操作
(2)任一写者在完成写操作之前不允许其它读者或写者工作
(3)写者执行写操作前,应让已有的写者和读者全部退出

2.问题分析

(1)共享数据(文件、记录)由Reader和Writer是两组并发进程共享
(2)Reader和Writer两组并发进程
(3)同组的Reader进程可同时对文件进行读,不用互斥
(4)写-写互斥
(5)读-写互斥

3.读者写者问题--读者优先

对于读者优先,应满足下列条件:
①如果新读者到:但有其它读者正在读,则新读者也可以读;
②有写者等待,但有其它读者正在读,则新读者也可以读;
③有写者写,新读者等待。

如果新写者到:
①无读者,新写者可以写;
②有读者,新写者等待;
③有其它写者,新写者等待。

4.信号量及变量设计

(1)对读进程计数变量:readcount=0
(2)对计数器操作的互斥信号量:rc_mutex=1
(3)读写互斥、写写互斥信号量:writeblock=1

5.读者优先算法设计

int readcount=0; //读进程计数器 
semaphore writeblock, rc_mutex ; 
writeblock=1; rc_mutex=1; 
main() { 
cobegin 
process reader_i( )//i=1,2,…n 
process writer_j( ) //j=1,2,…m 
coend 
}

process reader_i() 
{ 
P(rc_mutex); 
readcount++; 
if(readcount==1) 
P(writeblock); 
V(rc_mutex); 
{读文件}; 
P(rc_mutex); 
readcount--; 
if(readcount==0) 
V(writeblock); 
V(rc_mutex);
 } 


process writer_j( ) 
{ 
P(writeblock); 
{写文件}; 
V(writeblock); 
}

6.问题分析

(1)读者优先,当有读者时,写者将被推迟
(2)会出现写者饥饿现像

二、读者-写者问题:解决写进程饥饿现像

1.信号量设置

(1)信号量rw:用于保证读者和写者互斥的访问文件
(2)信号量mutex:用于保证count变量的互斥访问
(3)信号量w:用解决写者饥饿问题

2.算法设计

int count=0;            //用于记录当前的读者数量
semaphore mutex=1;      //用于保证count变量的互斥访问 
semaphore rw=1;         //用于保证读者和写者互斥的访问文件
semaphore w=1;          //用解决写者饥饿问题

void reader_i() 
{ 
while(1){
P(w);          //在无读写进程时请求进入
P(mutex); 
count++; 
if(count==1) 
P(rw); 
V(mutex); 
V(w);         //恢复对共享文件的访问
{读文件}; 
P(mutex); 
count--; 
if(count==0) 
V(rw); 
V(mutex);
 }
}

Void writer() 
{ 
while(1){
    P(w);         //在无写进程时请求进入
    P(rw);        //互斥访问共享文件
    {写文件};        //写入
    V(rw);       //释放共享文件
    V(w);        //恢复对共享文件的访问
}
} 


3.分析

当有读进程正在读共享文件时,有写进程请求访问,这时将会禁止后进读进程的请求,等到已在共享文件的读进程执行完毕,立即让写进程进入执行,只有在无写进程执行的情况下才允许读进程的再次运行,即解决了写进程饥饿的问题。

三、读者写者问题的应用---独木桥问题

类型1.一次只能过一辆车

1.问题描述

东西向汽车驶过独木桥,为了保证交通安全,只要桥上无车,则允许一方的汽车过桥,待其全部过完后才允许另一方的汽车过桥,限制桥面上一次只过一辆车。请用信号量和pv操作写出汽车过独木桥问题的同步算法。

2.问题分析

(1)系统中的进程
两类:从东向西行驶的汽车;从西向东行驶的汽车
(2)进程间的关系
①同向行驶的汽车需要排队;
②对向行驶的汽车需要同步,保证不能在独木桥上相遇

3.信号量设计

(1)mutexA:用于同向(从东向西)行驶的汽车对统计信息进行修改时的互斥信用量,初值为 1
(2)mutexB:用于同向(从西向东)行驶的汽车行驶的汽车对统计信息进行修改时的互斥信用量,初值为 1
(3)bridge:两个方向的汽车过桥的时的信号量,两个方向竞争此信号量,竞争成功的一方获得过桥资格,初值为 1
(4)mutex:过桥时的互斥信号量

4.算法设计

semaphore mutexA,mutexB,bridge,mutex; 
mutexA=1,mutexB=1,bridge=1,mutex=1; 
int countA=0,countB=0; 
main() { 
cobegin 
process east-to-west-i();//i=1,2,3…n 
process west-to-east-j();//j=1,2,3…m 
coend 
}
process east-to-west-i();//i=1,2,3…n 
{ p(mutexA); 
countA++; 
if(countA==1) p(bridge); 
v(mutexA); 
p(mutex); 
过桥; 
v(mutex); 
p(mutexA); countA--; 
if(countA==0) v(bridge); 
v(mutexA); 
} 
process west-to-east-j();//j=1,2,3….. 
{ 
{ p(mutexB); 
countB++; 
if(countB==1) p(bridge); 
v(mutexB); 
p(mutex); 
过桥; 
v(mutex); 
p(mutexB); 
countB--; 
if(countB==0) v(bridge); 
v(mutexB); 
}

类型2.一次能过多辆车

1.问题描述

东西向汽车驶过独木桥,为了保证交通安全,只要桥上无车,则允许一方的汽车过桥,待其全部过完后才允许另一方的汽车过桥,桥面上一次能过多辆车。请用信号量和pv操作写出汽车过独木桥问题的同步算法。

2.进程设计

两类进程:从东到西的汽车 PA 和从西到东的汽车 PB
(1)PA 进程:每辆汽车从东到西过桥的一次活动为一个进程
(2)PB 进程:每辆汽车从西到东过桥的一次活动为一个进程

3.信号量设计

(1)mutex1:用于 PA 进程之间对统计信息进行修改时的互斥信用量,初值为 1
(2)mutex2:用于 PB 进程之间对统计信息进行修改时的互斥信用量,初值为 1
(3)bridge:两个方向的汽车过桥的时的信号量,两个方向竞争此信号量,竞争成功的一方获得过桥资格,初值为 1
(4)number:同一方向过桥时的信号量,初值为 k

4.算法设计

semaphore mutex1=1, mutex2=1,bridge=1,number=k;int count1=0,count2=0; 
cobegin 
process PA_i()//i=1,2,….. 
{ 
p(mutex1); //对统计量 count1 写操作的互斥信号量 
count1++; 
If(count1==1) 
p(bridge)//第一个从东到西的汽车竞争桥的互斥信号量 
v(mutex1); 
p(number);// 同一方向的汽车过桥,同时可以过 k 辆 
过桥; 
V(number); 
p(mutex1); //对统计量 count1 写操作的互斥信号量 
coun1--; 
If(count1==0)
 v(bridge)//最后一个从东到西的汽车释放桥的互斥信号量 
v(mutex1); 
}

process PB_j()//j=1,2,….. 
{ 
p(mutex2); //对统计量 count1 写操作的互斥信号量 
count2++; 
If(count2==1) p(bridge)//第一个从东到西的汽车竞争桥的互斥信号量 
v(mutex2); 
p(number);// 同一方向的汽车过桥,同时可以过 k 辆 
过桥; 
V(number); 
p(mutex2); //对统计量 count1 写操作的互斥信号量 
coun2--; 
If(count2==0)
 v(bridge)//最后一个从东到西的汽车释放桥的互斥信号量 
v(mutex2); 
} 
coend 

四、总结

读者写者问题和生产者消费者问题的区别在于:
(1)同一时期内生产者消费者问题可以交替执行;而读者写者问题在同一时期内只能由一方执行,当开始执行时必须执行完所有读者(或写者),另外一方才能开始执行。
(2)生产者消费者共享的缓存区必须要互斥;读者写者共享的文件不一定需要互斥,当限制只有不可同时读或不可同时写时共享的文件才需要互斥。
(3)独木桥问题有点特殊,代码中未体现出同步,当一方的车辆全部通过桥面时,释放桥的使用权,由于全部车辆已经通过,目前这一方已经没有车辆了,自然另一方就会抢到桥的使用权,然后开始过桥,如此反复,从而体现出了同步。