操作系统(二十六)读者写者问题
2.3.9 读者写者问题
读者写者问题是十分经典的进程同步的问题,问题描述如下:读进程与写进程共享文件,但是写进程必须与其他进程互斥发生。
根据以上的题目要求我们可以得出一些互斥关系:写进程与写进程互斥,读进程与写进程互斥
我们可以设置一个互斥信号量rw来实现对互斥信号的共享访问
semaphore rw=1; //用于实现对共享文件的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”} }reader (){ while(1){P(rw); //读之前“加锁”读文件…V(rw); //读完了“解锁”} }但是这样简单的上锁解锁会导致读文件不能同时进行,就像我们进房间,打开门之后接着关上了门,后面的人当然没办法继续进来了。按照日常经验,开门应该有第一个人完成而关门应该有最后一个人完成,于是我们再次引入count计数器,记录正在读的进程数。
semaphore rw=1; //用于实现对共享文件的互斥访问 int count = 0; //记录当前有几个读进程在访问文件 semaphore mutex = 1;//用于保证对count变量的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”} }reader (){while(1){if(count==0) //由第一个读进程负责P(rw); //读之前“加锁”count++; //访问文件的读进程数+1读文件…count--; //访问文件的读进程数-1if(count==0) //由最后一个读进程负责V(rw); //读完了“解锁”} }这样做我们又会发现问题,如果两个读进程同时在count++前访问的话,P(rw)会这执行两次,那么第二个读进程会被阻塞。这是由于对count的检查以及赋值没有一气呵成(缺乏原子性)所以我们需要再来一个变量mutex实现对count互斥访问。
semaphore rw=1; //用于实现对共享文件的互斥访问 int count = 0; //记录当前有几个读进程在访问文件 semaphore mutex = 1;//用于保证对count变量的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”} }reader (){while(1){P(mutex); //各读进程互斥访问countif(count==0) //由第一个读进程负责P(rw); //读之前“加锁”count++; //访问文件的读进程数+1V(mutex);读文件…P(mutex); //各读进程互斥访问countcount--; //访问文件的读进程数-1if(count==0) //由最后一个读进程负责V(rw); //读完了“解锁”V(mutex);} }但是按照上述的代码来执行的话,写进程的操作总会被读进程的到来而阻塞,可能会导致读进程饥饿,我们再来添加一个互斥信号量w来实现公平读写(先来先服务)
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);} }读者-写者问题其核心思想在于设置了一个计数器 count 用来记录当前正在访问共享文件的读进程数。我们可以用count 的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理。
另外,对 count 变量的检查和赋值不能一气呵成导致了一些错误,如果需要实现“一气呵成”,自然应该想到用互斥信号量。
总结
以上是生活随笔为你收集整理的操作系统(二十六)读者写者问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 2021中国餐饮营销力白皮书
- 下一篇: 操作系统(二十七)管程