操作系统——读者写者问题(写者优先)

阅读前提醒:本文代码为伪代码,仅供理解!
马上就要被关得精神失常了,也许这是我的最后一条博客了吧……()
啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈水文来咯!!!!!

1.什么是读者写者问题

  • 一个数据文件或记录可被多个进程共享;我们把只要求读取该文件的进程称为“读者“,其余称为“写者”。

  • 当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。

简单来说,读者只对数据文件进行读取并不进行修改操作,读者和读者之间是不存在互斥的。

但是写者不一样,写者只有自己工作的时候时完成得最好的,但是他和其他进程一起工作的话是事倍功半的,因为写者与写者之间的想法是不一样的,如果他们要同时修改的话很容易导致数据冲突。又或者写者和读者一起工作,当读者刚好读取到写者正在修改的部分的时候,这个程序也将毫无意义。

2.优先的两种策略

①读者优先

总是给读者优先权,只要写者当前没有进行写的操作,读者就可以获得访问权。这样的优先策略主要应用于读者比较多且写者不需要经常更新的情况下,例如图书馆参考数据库。

②写者优先

通常把优先权交给写者,而将读者延迟到所有等待着的以及活动着的写者都完成了为止。这种情况主要应用于经常需要更新的系统,比如机票预订系统。

3.在写者优先策略之下

写者并不是拥有“绝对优先权”,写者不能无条件的打断读者的进程,他只能在进入队列后如果前面有正在工作的读者,要等待前一个读者结束了进程才能轮到他。

  • 读者和写者、写者和写者不能同时访问缓冲区
  • 无写进程时各读者可同时访问缓冲区
  • 读者和写者都等待时,写者优先访问缓冲区。

4.实现设计

①先过一遍代码

reader()
{
    while(true)
    {
        wait(read);//申请读取权限
        wait(RCSignal)//多个读者互斥
            if(!readCount)//如果读者队列为空,申请文件资源
                wait(fileSrc);
            readCount++;
        signal(RCSignal);//释放互斥信号量
        signal(read); //释放读取权限
        ……
            perform read operation//执行读取操作代码
            ……
         wait(RCSiganl);//多个读者互斥
         readCount--;
        if(!readCount) //如果读者队列为空,释放文件资源
            signal(fileSrc);
           signal(RCSignal);//释放互斥信号量
    }
}

②进程优先级互斥的表现

  • 因为写者读者互斥,所以我们引入第一个互斥信号量 read 并将之初始化为1
  • 读者对read的操作:其中读者申请到read后,在读操作前立即释放
  • 写者申请到了read后,占用其直至写者堵塞排队队列都完成工作

③临界资源的互斥

因为要实现进程对临界资源的互斥访问,所以我们引进信号量fileSrc

④读者写者等待进程数量

通过记录当前堵塞的写者进程数所以引入ReaderCount与Writer Count。相应的,因为ReaderCount与WriterCount也是可以被多个读者/写者进程访问的临界资源,因此我们也需要设置互斥信号量RCSignal与WCSignal。

⑤四个互斥信号量与两个变量

  • 进程优先互斥:read=1
  • 临界资源互斥:fileSrc=1
  • 多个读者互斥:RCSignal=1
  • 多个写者互斥:WCSiganl=1
  • 读者在读数:ReaderCount=0
  • 写者排队数:WriterCout=0

5.最终代码

①读者部分

reader()
{
    while(true)
    {
        wait(read);//申请读取权限
        wait(RCSignal)//多个读者互斥
            if(!readCount)//如果读者队列为空,申请文件资源
                wait(fileSrc);
            readCount++;
        signal(RCSignal);//释放互斥信号量
        signal(read); //释放读取权限
        ……
            perform read operation//执行读取操作代码
            ……
         wait(RCSiganl);//多个读者互斥
         readCount--;
        if(!readCount) //如果读者队列为空,释放文件资源
            signal(fileSrc);
           signal(RCSignal);//释放互斥信号量
    }
}

②写者部分

writer()
{
    while(true)
    {
        wait(writeCountSignal);//申请写者计数器资源
            if(!readCount)//如果当前写着队列为空则申请优先权限
                wait(read);
            writeCount++;
        signal(writeCountSignal);//释放写者计数器资源
        wait(fileSrc); //申请文件资源
        ……
            perform write operation//执行写操作代码
            ……
         signal(fileSrc);//释放文件资源
         wait(writeCountSignal);//多个写者互斥
         writeCount--;
        if(!writeCount) //如果写者队列为空,则允许读者进行操作
            signal(read);读者
           signal(writeCountSignal);//释放互斥信号量
    }
}

水完了……爬走了……886……

  • 18
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
Java实现读者-问题优先算法可以通过使用ReentrantReadWriteLock类来实现。该类提供了读锁定的机制,其中读锁定可以被多个线程同时持有,而锁定只能被单个线程持有。 下面是一个示例代码,实现了读者-问题优先算法: ``` import java.util.concurrent.locks.ReentrantReadWriteLock; public class WriterPriorityReadWriteLock { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); private int readers = 0; private int writers = 0; private int writeRequests = 0; public void startRead() throws InterruptedException { readLock.lock(); try { while (writers > 0 || writeRequests > 0) { wait(); } readers++; } finally { readLock.unlock(); } } public void endRead() { readLock.lock(); try { readers--; notifyAll(); } finally { readLock.unlock(); } } public void startWrite() throws InterruptedException { writeLock.lock(); try { writeRequests++; while (readers > 0 || writers > 0) { wait(); } writeRequests--; writers++; } finally { writeLock.unlock(); } } public void endWrite() { writeLock.lock(); try { writers--; notifyAll(); } finally { writeLock.unlock(); } } } ``` 在这个实现中,读者者线程都可以通过调用startRead()和startWrite()方法来获取锁定,然后通过调用endRead()和endWrite()方法来释放锁定。在优先算法中,如果存在等待的者,则新的读者线程必须等待所有等待的者完成。 需要注意的是,如果有多个者在等待锁定,则它们将按照先来先服务的顺序获得锁定。因此,这种实现可能会导致饥饿现象,即某些线程可能会无限期地等待。为了避免这种情况,可以采用其他的算法,例如读者优先算法或者公平算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AKA山风点火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值