燕山大学操作系统作业——读者-写者公平问题
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了燕山大学操作系统作业——读者-写者公平问题相关的知识,希望对你有一定的参考价值。
PS:这文章是软件后四个班(李贤善老师教的班)的作业,前四个班的作业在下面的下载链接里:
https://download.csdn.net/download/weixin_45525272/29795260
这也不是标准答案,只是我自己的见解,总结出来的,仅供参考,如有错误,可以评论留言或者加QQ1795018360,请不吝赐教。
燕山大学操作系统大作业
问题:
教材中提供的读者-写者问题的解决方案存在读者优先问题,即当有一个读进程比较活跃时,随后而来的读进程都将被允许访问资源。这样,会导致写进程可能长时间等待。而这种情况往往与实际应用需求相背。
请认真分析、研究读者-写者问题,给出对读者和写者都较为公平的同步解决方案。要求写出分析过程,写出使用的信号量及进程描述伪代码,并详细解释给出的解决方案。
解决方案:
1.问题探讨:
教材中为读者优先,其特点有写者、读者互斥访问文件资源,多个读者可以同时访问文件资源(通过readcount
来控制),只允许一个写者进行写的操作(通过wmutex
控制),只要有读者这在读,就不允许写者进入。直到没有读者到达,没有读者到达会导致读者队列为空,即readcount =0
,此时写者才可以进入临界区执行写操作。
由此可看出除非有写者在写,否则读者不需要等待,读者处于高优先级进程,写者处于低优先级进程,两者通过变量wmutex
完成互斥。从而导致写进程长时间的等待。
这相对于写者来说是非常不公平的,举个例子,如果连续一直有读者进行读操作的时候,写者就不能访问系统资源临界区进行写操作。
1.1.改进:
首先我想到可以将待访问的数据区域视为临界区,直接只设置一个互斥信号量mutex
,然后读者和写者都采用 p(mutex);
读取/写入数据; v(mutex);
的方式竞争获取数据区域。这样的方法也可以做到先到先得的效果啊。
虽然达到了读者-写者公平竞争,但是上面忽视了一个严重的问题:丧失了读者的并行性。下面再进行改进。
1.2.升级:
我首先想:能不能为读者队列加一个锁,将没进来的锁在外面,即形成两个读者队列:在有写者想要写的时候分成已经读上的读者和没有读上的读者。然后已经读上的读者继续读直到读完为止,再想读的读者就不让读了。当已经读上的读者读完了的时候进来的写者进行写操作。
大致意思就是:当写者没有写的时候,读者直接进入读者队列等待系统分配资源进行读取数据;但是当有写者要进行写操作的时候,立刻开启读者队列锁,新来的再想进行读操作的读者就不能读了,只有已经读上的可以进行读操作,当读者队列读完了的时候,写者进行写,写完解除读者队列锁。新来的再想读的读者就可以正常读了。
好了,上面那就是想的过程,下面整点专业的代码和语句。
2.问题解决:
2.1.设计规则:
- 首先读者、写者肯定要互斥访问
- 同一时刻只能允许有一个写者访问资源
- 同一时刻可以有多个读者同时访问资源
- 读者进程分为两个级别
- 写者进程的优先级和读者相同
2.2.实现方法
- 设置fmutex 信号量实现对临界资源的互斥访问。
- 设置计数器readcount实现多个读者访问临界资源,通过设置信号量rmutex 实现对readcount 计数器的互斥访问。
- 设置信号量fair实现读者进程和写者进程的公平竞争
2.3.实现原理:
信号量fair的作用其一是为了阻止读者进程优先(即教材中的只要读者进程到达,就可以进入读者队列,而写者进程必须等待,有了fair可以阻塞没读的读者),其二是为了写者间的互斥(有了fair只有当前一个写者可以进行写操作)。
例如:开始来了一些读者进程读资源,此时没有写者那么全部进入读者队列,此时来了一个写者,执行P(fair)操作,使得后续到来的读者都阻塞在fair上,不能进入读者队列(这会使得读者队列逐渐为空,即rcount减为0),但是这个写者也不能立马开始写(因为此时读者队列不为空),阻塞在fmutex 上,读者队列中的读者全部读取结束后,最后一个读者进程执行V(fmutex),唤醒刚才的写者,写者开始进行写操作。
2.4.伪代码实现:
//公平竞争
int readcount = 0;
semaphore rmutex = 1; // 用于读者进程互斥修改readcount;
semaphore fmutex = 1; // 用于读者和写者互斥访问文件
semaphore fair = 1; // 用于实现公平竞争,锁住新进读者队列
// 写者操作
writer()
P(fair); // 读者队列
P(fmutex);
...
写者操作
...
V(fmutex);
V(fair);
// 读者操作
reader()
P(fair);
P(rmutex);
if (readcount == 0)
P(fmutex);
readcount ++;
V(rmutex);
V(fair);
...
读者操作
...
P(rmutex);
readcount --
if (readcount == 0)
V(fmutex);
V(rmutex);
以上是关于燕山大学操作系统作业——读者-写者公平问题的主要内容,如果未能解决你的问题,请参考以下文章
操作系统——读者写者问题(读者优先强写者优先 和 公平竞争)