读者写着问题(PV操作)

410 阅读3分钟

这是我参与18月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

上一次分享的是生产者消费者问题 今天分享读者写着问题:

  • 描述: 读者与写着共享一个文件,多个读者可以同时访问这个文件,但读者和写着进程同时访问这个文件则不行且只能有一个读者访问这个文件。 在上述问题中我们要抓住的关键点是:访问文件,若是多个读者则可以同时访问,若是写着则只能一个写者访问文件 读者和写着也要互斥访问

  • 分析: 我们需要那些信号量:写者与读者访问文件时要互斥访问,所以需要一个信号量rw;可以有多个读者访问文件所以引入count变量来记录访问文件的读者数量,但是如果不对count这个变量进行互斥访问则也会出现读者阻塞情况 故需要一个访问count的互斥信号量mutex

PV操作

semaphore rw = 1;
int count = 0;
semaphore mutex = 1;
//写进程
P(rw) ;
写文件
V(rw);

//读进程
P(mutex) //先要互斥试用count变量
if(count == 0) {P(rw);}
count++;
V(mutex)  //释放对count的占用 以便下一个读者进来使用
读文件
P(mutex)
 count--;
if(count==0){V(rw)}; //最后一个读者离开就要释放对文件的占用
V(mutex)

仔细读上面的pv 你会发现 如果读者一直在增加 那么写者就会一直不能写数据 写者可能会出现饿死的过程(这个操作是一个读者优先的) 我们针对上面出现的情况 如何进行改进呢? 我们只需要再加一个信号量 w 用来实现写优先

semaphore rw = 1;
int count = 0;
semaphore mutex = 1;
semaphore w =1;
//写进程
P(W)
P(rw) 
写文件
V(rw)
V(W)

//读进程
P(W)
P(mutex) //先要互斥试用count变量
if(count == 0) {P(rw);}
count++;
V(mutex)  //释放对count的占用 以便下一个读者进来使用
V(w)
读文件
P(mutex)
 count--;
if(count==0){V(rw)}; //最后一个读者离开就要释放对文件的占用
V(mutex)

根据上面的操作可以实现一下:读进程A访问文件,此时写进程B也想要访问文件,他执行P(w)是可以的 但是执行P(rw)则会阻塞,会等待读进程A访问完才能继续执行 若读进程C也想要访问文件 他会执行P(w)则就会阻塞,他必须要要等写进程B执行完才能执行 则也就实现了写进程优先

在这次的读者写着进程中相比与上一次分享的生产者消费者进程又更复杂一些,而在这个pv操作中 对于计数器count的使用是我们需要关注的 需要了解这个解决问题的思路