鉴于我在csdn都没找到标准的Readers-Writers Problem的解法,由此写这份blog并指出搜索首页那几篇解决办法不足之处。
读者-写者基本解法
- 基本解法是读者优先解法
- 允许多个读者读
- 读写互斥,写者之间互斥
typedef int semaphore
semaphore mutex = 1, w =1;
int readcount = 0;
reader()
{
P(mutex); // 控制readcount访问
readcount++;
if(readcount == 1) P(w); // 排斥写访问
V(mutex);
//read
P(mutex); // 控制read count访问
readcount--;
if(readcount == 0) V(w); // 恢复写访问
V(mutex);
}
writer()
{
P(w); // 排斥写访问
//write
V(w); // 恢复写访问
}
写者优先解法
读者优先写法大家都没什么大问题,主要是写者优先解法大家总有不足的地方,此处我贴出Courtois于1971年论文的解决办法(Concurrent Control with “Readers” and “Writers”)
- 允许多个读者读
- 允许多个写者写
- 读写互斥,写者之间互斥
- 绝对地写者优先
typedef int semaphore
semaphore mutex1 = 1, mutex2 = 1, mutex3 = 1, w = 1, r =1;
int readcount = 0, writecount = 0;
reader(){
P(mutex3); // 真正控制写优先
P(r); // 排斥读访问
P(mutex1); // 控制readcount访问
readcount++;
if(readcount == 1) P(w); // 排斥写访问
V(mutext1);
V(r); // 恢复读访问
V(mutex3);
//read
P(mutex1); // 控制readcount访问
readcount--;
if(readcount == 0) V(w); // 恢复写访问
V(mutex1);
}
writer(){
P(mutex2); // 控制writecount访问
writecount++;
if(writecount == 1) P(r); // 排斥读访问
V(mutex2);
P(w); // 排斥写访问
//write
V(w); // 恢复写访问
P(mutex2); // 控制writecount访问
writecount--;
if(writecount == 0) V(r); // 恢复读访问
V(mutex2);
}
网上流传的写者优先版本大多数在读者的进程中少了mutex3的信号量判断。少数篇章例如nextSecond.博主写的读者进程带有着mutex3信号量,但是代码写的有问题,缺少mutex3信号量的V操作(signal操作)。这里引用论文原文:
mutex3 is necessary because of our absolute insistence on priority for Writers. Without mutex 3 we have the possibility that a writer and one or more readers will be simultaneously waiting for a V(r) to be done by a reader .
翻译:为了保证绝对的写者优先,mutex3是必须的。如果没有了mutex3,我们有可能在读者进程执行完V(r)操作后,出现写进程和读进程同时对r信号量访问的情况。
最后就不阐述公平竞争的例子。因为它的实现是并发性低的,性能差的。