读者-写者问题改进
一、问题(读者优先)
教材中提供的读者-写者问题的解决方案存在读者优先问题,即当有一个读进程比较活跃时,随后而来的读进程都将被允许访问资源。这样,会导致写进程可能长时间等待。而这种情况往往与实际应用需求相背。请认真分析、研究读者-写者问题,给出对读者和写者都较为公平的同步解决方案。
教材方案(读者优先):
semaphore rmutex = 1, wmutex = 1;
int readcount = 0;
void Reader(){
while(1){
wait(rmutex);
if(readcount==0) wait(wmutex);
readcount++;
signal(rmutex);
...
perform read operation;
...
wait(rmutex);
readcount--;
if(readcount==0) signial(wmutex);
signal(rmutex);
}
}
void Writer(){
while(1){
wait(wmutex);
...
perform write operation;
...
signal(wmutex);
}
}
二、分析
教材中规定: 写者、读者互斥访问文件资源,只要有读者还占有资源,就不允许写者进入。
此时就出现了问题,当一直有读者或多个读者轮流长时间占据资源,写者会长时间等待,无法获得资源。
上述方法就是读者优先。
三、改进方案
1.公平竞争
在教材方法中,一旦读者获得资源,wmutex就会一直小于1,直到所有读者进程结束为止,写者甚至没有竞争资源的机会。
那么,可以就再添加一个信号量,给写者竞争的机会。
如果写者抢到资源,就不能再有其他读者新的读者阅读。接下来只要等待还在阅读的读者全部结束,写者就可以拿到资源。
semaphore rmutex = 1, wmutex = 1, w = 1;
int readcount = 0;
void Reader(){
while(1){
wait(w);
wait(rmutex);
if(readcount==0) wait(wmutex);
readcount++;
signal(rmutex);
signal(w);
...
perform read operation;
...
wait(rmutex);
readcount--;
if(readcount==0) signial(wmutex);
signal(rmutex);
}
}
void Writer(){
while(1){
wait(w);
wait(wmutex);
...
perform write operation;
...
signal(wmutex);
signal(w);
}
}
2.写者优先
由上述两个问题,可以想到,当存在多个写者时,也可以使用写者优先。
同读者优先,只需在写者占有资源后,不允许读者进入,代码基本一致,但需要调整信号量位置来避免死锁。
添加信号量 w_cs : 保证临界区的资源只能有一个写者修改,并实现了读者执行时写者等待。
semaphore rmutex = 1, wmutex = 1, w = 1, w_cs = 1;
int readcount = 0, writecount = 0;
void Reader(){
while(1){
wait(w);
wait(rmutex);
if(readcount==0) wait(w_cs);
readcount++;
signal(rmutex);
signal(w);
...
perform read operation;
...
wait(rmutex);
readcount--;
if(readcount==0) signial(w_cs);
signal(rmutex);
}
}
void Writer(){
while(1){
wait(wmutex);
if(writecount==0) wait(w);
writecount++;
signal(wmutex);
wait(w_cs)
...
perform write operation;
...
signal(w_cs)
wait(wmutex);
writecount--;
if(readcount==0) signial(w);
signal(wmutex);
}
}
写者优先优化:
如果在写者执行时,有多个读者进入,可能会出现多个读者等待的情况。例如,当第一个读者signal(w)
时,第二个读者或者更多的读者此时会和写者同时处于wait(w)
的状态,写者无法跳过该长队列,需要和其他读者抢资源,这不符合写者优先。
可以添加一个信号量 q ,写在读者的wait(w)
之前。这样只有一个读者可以在wait(w)
前排队,其他必须在wait(q)
前排队,这样可以让写者优先抢到资源,满足了写者优先。
semaphore rmutex = 1, wmutex = 1, w = 1, w_cs = 1, q = 1;
int readcount = 0, writecount = 0;
void Reader(){
while(1){
wait(q);
wait(w);
wait(rmutex);
if(readcount==0) wait(w_cs);
readcount++;
signal(rmutex);
signal(w);
signal(q);
...
perform read operation;
...
wait(rmutex);
readcount--;
if(readcount==0) signial(w_cs);
signal(rmutex);
}
}
void Writer(){
...
}
参考博客:
读者写者问题(超级详细的分析读者优先,读写平等,写者优先)_Rqff的博客-****博客_读者优先的读者写者问题
读者写者问题(读者优先,写者优先 ,读写公平)_骐骥一跃,不能十步;驽马十驾,功在不舍。-****博客_读者写者问题