读者写者问题
问题描述

问题分析
这个问题,互斥问题是主要要考虑的事情。
难点 1:有多个读者,数量不定。无法使用固定数量的信号量表示。
互斥:
- 写者与写者互斥;
- 读者和写者互斥;
代码实现
不合理实现
sem rw = 1; // 用于解决写者和读者的互斥
sem mutex = 1;
int count = 0; // 表示当前有多少的读者
void writer() {
while (1) {
P(rw);
...
V(rw);
}
}
void reader() {
while (1) {
P(mutex);
if (count == 0) {
P(rw);
}
count++;
V(mutex);
P(mutex);
count--;
if (count == 0) {
V(rw);
}
V(mutex);
}
}
解读
上述实现会出现的问题是如果有源源不断地读进程加入,就会一直不释放 rw,从而导致写进程一直无法工作,造成饥饿的现象。
优化实现
解决办法就是让写进程优先。即加上同步关系,让写进程在任何时候都有机会进行写操作。
sem w = 1;
void writer() {
while (1) {
P(w);
P(rw);
...
V(rw);
V(w);
}
}
void reader() {
while (1) {
P(w);
P(mutex);
if (count == 0) {
P(rw);
}
count++;
V(mutex);
V(w);
读文件...
P(mutex);
count--;
if (count == 0) {
V(rw);
}
V(mutex);
}
}
解读
- 当写进程占据了 w 后,读进程无法继续增加,当写进程进一步占据 rw 后,所有读进程就无法继续执行读操作了。
- 若读进程率先占据 w,那么写进程因为 w 而阻塞。此时读进程继续占据 rw,但是随后将释放 w,此时写进程就可以占据w,以防止其他读进程继续改变 count 值。当那个释放 w 的读进程释放了 rw 后,写进程就必然可以进行工作。
- 可以用并发顺序:读者1->写者1->读者2,进行模拟运行。