燕山大学操作系统作业——读者-写者公平问题

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.设计规则:

  1. 首先读者、写者肯定要互斥访问
  2. 同一时刻只能允许有一个写者访问资源
  3. 同一时刻可以有多个读者同时访问资源
  4. 读者进程分为两个级别
  5. 写者进程的优先级和读者相同

2.2.实现方法

  1. 设置fmutex 信号量实现对临界资源的互斥访问。
  2. 设置计数器readcount实现多个读者访问临界资源,通过设置信号量rmutex 实现对readcount 计数器的互斥访问。
  3. 设置信号量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);  
  

以上是关于燕山大学操作系统作业——读者-写者公平问题的主要内容,如果未能解决你的问题,请参考以下文章

操作系统——读者写者问题(读者优先强写者优先 和 公平竞争)

读者写者问题(读者优先 写者优先 读写公平)

读者写者问题(读者优先 写者优先 读写公平)

信号量解决写者优先&读者优先&公平竞争(reader writer)

操作系统-进程PV操作——读者写者问题

用C语言编程实现用信号量实现读者--写者问题(要源代码)