读者-写者问题
有读者和写者两组并发进程,共享一个文件,要求:
- 允许多个读者进程同时对共享文件执行读操作
- 只允许一个写者进程往里写数据
- 任意一个写者进程在完成写操作之前不允许其他读者进程或者写者进程访问共享文件
- 写者执行写操作前,应等到已有的读者进程和写者进程全部退出
关系分析:
- 只有2类进程,写进程、读进程
- 互斥关系:写进程-写进程,写进程-读进程
semaphore rw = 1;//用于实现对共享文件的互斥访问
int count = 0;//用于统计读者进程访问文件数量,第一个读者上锁,最后一个读者离开解锁
semaphore mutex = 1;//用于保证对count变量互斥访问
writer(){
while(1){
P(rw);//写之前上锁
写文件
V(rw);//写完后解锁
}
}
reader(){
while(1){
P(mutex);
if(count==0){
P(rw);
}
count++;
V(mutex);
读文件
P(mutex);
count--;
if(count==0){
V(rw);
}
V(mutex);
}
}
上面是读者进程优先,如果一直有读者进程到来,那么写进程就会被饿死,一直没有等到cpu调度,怎么解决这个问题呢
我们可以再设置一个互斥信号量,当写者进程想要往里写入数据时,只允许当前的读者继续运行,直到结束,期间不允许其他读者到来
代码优化!!!
semaphore rw = 1;//用于实现对共享文件的互斥访问
int count = 0;//用于统计读者进程访问文件数量,第一个读者上锁,最后一个读者离开解锁
semaphore mutex = 1;//用于保证对count变量互斥访问
semaphore w = 1;//用于读写公平
writer(){
while(1){
P(w);
P(rw);//写之前上锁
写文件
V(rw);//写完后解锁
V(w);
}
}
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);
}
}
读者1->读者2,right
写者1->写者2,right
写者1->读者1->写着2,right
读者1->写者1->读者2,right
读者-写者问题的核心思想在设置了一个计数器count,来记录正在访问共享文件的读进程数,我们可以用count的值判断是第一个读者进程还是最后一个读者进程做业务逻辑处理。
另外对count变量的检查和赋值不能够一气呵成,比如2个读进程并发访问文件,对count值会有影响,我们应该想到互斥信号量
最后我们还解决了写进程饥饿问题,实现读写公平。
补充:这里的信号量默认是结构体变量,也就是会有个链式队列记录堵塞进程,资源空闲时会按序唤醒堵塞进程进入就绪队列。