我很难理解读者 - 作家问题的第二个算法。我理解一般的概念,作家将优先于读者(读者可能会饿死)。我甚至理解这个算法Reader/Writer Locks in C++的条件变量实现。但是,信号量&互斥实现对我没有意义。这是维基百科的一个例子:
int readcount, writecount; (initial value = 0)
semaphore mutex 1, mutex 2, mutex 3, w, r ; (initial value = 1)
READER
P(mutex 3);
P(r);
P(mutex 1);
readcount := readcount + 1;
if readcount = 1 then P(w);
V(mutex 1);
V(r);
V(mutex 3);
reading is done
P(mutex 1);
readcount := readcount - 1;
if readcount = 0 then V(w);
V(mutex 1);
WRITER
P(mutex 2);
writecount := writecount + 1;
if writecount = 1 then P(r);
V(mutex 2);
P(w);
writing is performed
V(w);
P(mutex 2);
writecount := writecount - 1;
if writecount = 0 then V(r);
V(mutex 2);
[http://en.wikipedia.org/wiki/Readers-writers_problem][2]
我不明白读卡器锁中的三个信号量(互斥锁3,r和互斥锁1)是什么。对于readcount,不是一个信号量足够吗?
答案 0 :(得分:10)
mutex 1
保护readcount
变量; mutext 2
保护writecount
变量;互斥r
保护读取操作,而静音w
保护写操作。
1)让我们假设一位作家进来:
信号mutex 2
并递增writercount
以考虑额外作者(本身)
由于它是唯一可以更改writercount
(因为它保持mutex 2
)的进程,因此可以安全地测试它是否是唯一的编写器(writercount==1
),如果为true,则表示互斥锁r
以保护读者不会进入 - 其他作者(writercount > 1
)可以享受已经发出信号的互斥r
。
然后,编写者发出互斥信号w
的信号,以保护其更改免受其他(并发)编写者的影响。
最后一位作家(writecount==1
)发布互斥r
,让读者执行任务。
2)让我们假设读者进来了:
信号mutex 3
以保护读者的设置逻辑免受其他读者的影响;然后发信号通知互斥r
以保护其他编写者(请记住,当编写器正在运行时,r
会发出信号);然后发出mutex 1
信号以保护读取数(来自可能正在退出的其他读者),如果它是第一个读者(readercount == 1
),则发信号通知互斥w
以防止作者(现在不包括作者)执行他们的行动。)
阅读可以并行完成,因此在阅读时不需要其他读者的保护(记住,此时正在保持互斥w
,所以没有来自作者的干扰)
然后最后一个读者重置写互斥(w
)以允许编写者。
阻止作家饥饿的伎俩是作者构成读者(当发信号为p
时),因此即使有很多读者,也很有可能获得预定。另外,mutex 3
会阻止太多读者等待互斥r
,因此作家很有机会在r
来时发出信号。
答案 1 :(得分:4)
查看Concurrent Control with "Readers" and "Writers" by P.J. Courtois, F. Heymans, and D.L. Parnas,这是维基百科代码的参考。它解释了为什么所有的互斥体都需要。