问题描述:对于同一个文件,读操作可以同时并行,读写操作互斥,写与写互斥。本质上就是同类进程不互斥,异类进程互斥的问题。
全都互斥
最简单的解法:
semaphore lock = 1;
Reader(){ // 读者进程
while(1){
P(lock);
读文件;
V(lock);
}
}
Writer(){ // 写者进程
while(1){
P(lock);
写文件;
V(lock);
}
}问题:读者和读者之间每次也要pv,会卡在p(lock)时,现在需要想办法跳过pv操作。
读优先(写优先同理)
思路:让第一个进程加锁🔒,最后一个进程解锁🔓。这样中间的进程就可以不pv, 直接使用啦。
semaphore lock = 1;
int count = 0; // 记录有多少个在使用
Reader(){ // 读者进程
while(1){
if(count == 0) // 第一个来的上锁
P(lock);
count++;
读文件;
count--;
if(count == 0) // 最后一个走的释放锁
V(lock);
}
}
Writer(){ // 写者进程
while(1){
P(lock);
写文件;
V(lock);
}
}
然而,count的访问需要互斥,否则数据就会冲突
添加互斥访问代码:
semaphore lock = 1;
mutex count_lock = 1; // 互斥访问变量 count
int count = 0; // 记录有多少个在使用
Reader(){ // 读者进程
while(1){
p(count_lock);
if(count == 0) // 第一个来的上锁
P(lock);
count++;
V(count_lock);
读文件;
p(count_lock);
count--;
if(count == 0) // 最后一个走的释放锁
V(lock);
V(count_lock);
}
}
Writer(){ // 写者进程
while(1){
P(lock);
写文件;
V(lock);
}
}
不允许读者或写者饿死
其实就是运行写进程插队执行。
semaphore rw = 1; // 读写锁
semaphore w = 1; // 写锁
mutex count_lock = 1; // 互斥访问变量 count
int count = 0; // 记录有多少个在使用
Reader(){ // 读者进程
while(1){
P(w);
p(count_lock);
if(count == 0) // 第一个来的上锁
P(rw);
count++;
V(count_lock);
V(w);
读文件;
p(count_lock);
count--;
if(count == 0) // 最后一个走的释放锁
V(rw);
V(count_lock);
}
}
Writer(){ // 写者进程
while(1){
P(w);
P(rw);
写文件;
V(rw);
V(w);
}
}
这样,当有读进程在执行是来了个写进程,写进程在P(w)成功后会卡在P(rw)上,这时后来的读进程会卡在P(w),直到现有的所有读进程执行完并释放锁。释放后写进程就可以插队成功啦。