四、操作系统——读者写者问题(详解)
一、问题描述:
二、需要满足的条件:
- 写进程与写进程之间必须互斥的写入数据(因为如果两个写进程同时对共享数据中的区域A中的数据进行写操作的话,会导致数据错误覆盖的问题)
- 写进程与读进程之间必须互斥的访问共享数据(因为写进程与读进程如果同时访问共享数据,可能会导致数据不一致的问题。比如:读进程A想要访问共享数据中的B数据,但是写进程C在读进程A访问B数据之前将B数据进行了更新,这就会导致读进程A读不到它想要读到的数据,从而出现数据不一致问题)
- 读进程与读进程之间可以同时访问数据,不需要实现互斥的访问共享数据(因为读进程读数据,并不会像之前的生产者消费者问题中的消费者那样改变数据或者是将数据清空,所以多个读进程可以同时访问共享数据)
三、解题思路:
- 第一步解决写进程与写进程之间必须互斥的写入数据 和 写进程与读进程之间必须互斥的访问共享数据 两个问题。
上面这种实现方式确实解决了了写进程与写进程之间必须互斥的写入数据 和 写进程与读进程之间必须互斥的访问共享数据 这两个问题。但是,
假设读进程A正在访问共享数据,执行了P(rw) 和 读数据操作,还没有执行V操作解锁,此时读进程B也想访问共享数据,此时,读进程B会卡在P(rw)中的循环里面,也就是说进程B被阻塞了。
读进程与读进程之间也变成了必须互斥访问共享数据,并不满足题目读进程与读进程可以同时访问共享数据的要求!
- 下面来实现多个读进程可以同时访问共享数据
解决方法:
引入count变量,用来记录当前有几个读进程在访问共享数据。
上述实现方法表面上看达到了实现多个读进程可以同时访问共享数据的目的,但其实还是存在问题的。
存在的问题:
如果读进程A想要访问共享数据,并且执行了P(rw)“上锁”操作,此时,读进程B也想要访问共享数据,也会执行P(rw),但是因为进程A已经执行了“上锁”操作,所以进程B还是会被阻塞,无法访问共享数据。可见,仍然没有达到多个读进程可以同时访问共享数据的目的!
出现这种问题的原因:
对于count变量的检查与赋值操作无法“一气呵成”,可以被中断。
解决方法:
可以增加一个mutex互斥信号量来保证if判断语句 和 count++(count–) 能够“一气呵成”执行完,中间不会被打断,保证各进程对count的访问是互斥的。
上述解决方案确实已经达到了多个读进程可以同时访问共享数据的目的,但此时,又出现了新的问题:只要又读进程在读取共享数据,写进程就要一直阻塞等待,这很可能导致写进程一直无法往共享数据中写入数据,也就是说写进程很有可能会被“饿死”。因此,这种算法中,读进程是优先的!下面我们来解决写进程可能会被“饿死”这个问题
解决方法:
设置变量semaphore w =1 ,用于实现“写优先”。然后分别为读进程、写进程增加关于信号变量w的P、V操作。
经过上面的“改造”,我们来验证一下是否达到了“写优先”的目的:
读进程A——>写进程a——>读进程B:
假设读进程A正在访问共享数据,那么读进程A肯定已经执行了P(w)、P(mutex)、P(rw)、V(mutex)、V(w)。此时,写进程a也想要访问共享数据,那么当读进程a执行P(w)时,不会被阻塞,但是执行到P(rw)时,由于读进程A还没有执行V(rw)“解锁”操作,所以,写进程a会被阻塞等待。
而如果此时有第二个读进程B也想要访问共享数据,但由于之前第一个读进程A已经执行了P(w)“上锁”操作,所以当读进程B执行到P(w)操作时,也会被堵塞等待。
直到读进程A完成了读文件操作后,执行了V(rw)“解锁”操作,写进程a才会被“唤醒”。然后在写进程完成了写文件操作后,执行了V(w)“解锁”操作,读进程B才能被唤醒。
注意:这里为什么会先唤醒写进程a呢?
答:因为这里是写进程a比读进程B先想要访问共享数据,所以优先被唤醒。这里其实就是“先来先服务算法”
结论:
在这种算法中,连续进入的多个读进程,可以同时读文件;写进程和其他进程不能同时访问文件;写进程不会“饥饿”。但也并不是真正的“写优先”,而是遵循相对公平的先来先服务原则。有的也称这种算法为“读写公平法”。
四、总结:
读者-写者问题为我们解决复杂的互斥问题提供了一个参考思路:
其核心思想在于设置了一个计数器count用来记录当前正在访问共享文件的读进程数。我们可以用count的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理。如果是第一个进程则执行“上锁”操作,如果是最后一个进程则执行“解锁”操作。
另外,对count变量的检查和赋值不能一气呵成导致了一些错误,如果需要实现“一气呵成”,自然应该想到用互斥信号量。
最后,还要认真体会我们是如何解决“写进程饥饿”问题的。
绝大多数的PV操作大题都可以用之前介绍的几种生产者-消费者问题的思想来解决,如果遇到更复杂的问题,可以想想能否用读者写者问题的这几个思想来解决。
四、操作系统——读者写者问题(详解)相关推荐
- java 读者写者_Java实现生产者消费者问题与读者写者问题详解
1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两 ...
- 读者写者问题详解 操作系统
2.16 读者写者问题 抽象解释 多个进程访问一个共享的数据区 读者(读进程)只能读数据,写者(写进程)只能写数据 适用于数据库.文件.内存.寄存器等数据区的访问模型 如12306购票系统,由于用户量 ...
- 操作系统之多线程编程—读者优先/写者优先详解
操作系统之进程调度--优先权法和轮转法(附上样例讲解) 操作系统之银行家算法-详解流程及案例数据 操作系统之多线程编程-读者优先/写者优先详解 操作系统之存储管理--FIFO算法和LRU算法 操作系统 ...
- 从头开始写STM32F103C8T6驱动库(四)——编写延时函数,详解Systick
系列文章目录 Github开源地址 从头开始写STM32F103C8T6驱动库(一)--STM32CubeMX创建并调整工程结构 从头开始写STM32F103C8T6驱动库(二)--编写系统初始化程序 ...
- 操作系统I/O控制方式详解
操作系统I/O控制方式详解 一.导读 二.I/O控制方式 1.直接程序控制方式 2.中断驱动控制方式 3.直接存储器访问(DMA)控制方式 4.通道控制方式 I/O控制方式有几种?分别适用何种场合? ...
- c语言写扫雷新手详解
c语言写扫雷新手详解 一.用到的知识点 1.分支语句 2.循环语句 3.二维数组 4.最好分块,使代码的功能更加独立,思维逻辑更加清楚,此程序我写了:test.c用来存放我的主函数,game.h用来定 ...
- linux日志配置含义,Linux操作系统中的日志功能详解
日志系统将我们系统运行的每一个状况信息都使用文字记录下来,这些信息有助我们观察系统运行过程中正常状态和系统运行错误时快速定位错误位置的途径等;下面学习啦小编主要概述一下Linux操作系统中的日志功能. ...
- MybatisPlus学习(四)条件构造器Wrapper方法详解
https://www.cnblogs.com/xianz666/p/13857733.html MybatisPlus学习(四)条件构造器Wrapper方法详解 文章目录 1.条件构造器 2.Que ...
- php shell,php命令行写shell实例详解
php 可以像java perl python 那样运行,今天发现如果我早早知道这个,或许我不会去学习java 和 python 当年学java不过为了一个程序放在服务器上,不停的跑啊跑,原来 php ...
- 安卓判断服务器返回的状态码,关于服务器返回的十四种常见HTTP状态码详解
原标题:关于服务器返回的十四种常见HTTP状态码详解 HTTP状态码 状态码是由3位数字和原因短语组成的(比如最常见的:200 OK),其中第一位数字表示响应类别,响应类别从1到5分为五种 add:其 ...
最新文章
- 扑克牌排序_JAVA 扑克牌排序打印,并进行洗牌
- 2016弱校联萌十一专场10.2
- CTFshow php特性 web144
- 面向接口编程详解(三)——模式研究
- 拷贝的Android源码不能单独编译mmm命令提示找不到
- Hadoop1.2.1集群安装三
- Mule,目前综合状态最良好的开源ESB方案引文
- RUNOOB python练习题24 斐波那契数列的衍生问题
- 股票型基金和期货有什么区别?
- div模拟textarea在ios下不兼容的问题解决
- 微软发布的新开源编程语言 Power Fx
- SQL Server2008 错误源:.net SqlClient data provider的解决方法
- c语言是高级编程语言吗,C语言是高级编程语言吗?
- Dubbo视频教程《基于Dubbo的分布式系统架构视频教程》--课程列表
- 用Python写了一个前端,轻轻松松实现前端梦
- 神经网络控制系统设计,神经网络技术及其应用
- 熊出没机器人光头强_熊出没:光头强的最强发明,第2件砍树神器,最后1件价值千万!...
- iPhone之手势切换图片
- Windows10+CentOS 7 双系统安装
- react学习的一些网站
热门文章
- 背单词软件 单词风暴 分享id_周一考研高效背单词系列(一):利用单词软件如何背好单词...
- MATLAB 长度和像素_Matlab中短时傅里叶变换 spectrogram和stft的用法
- 理解C++中拷贝构造函数
- mfc中UpdateData的用法
- 美国计算机专业硏究生,2014年美国计算机专业研究生排名
- tornado框架基础11-tornado异步
- CS224n笔记3 高级词向量表示
- setTimeOut函数传参数
- (机器学习/计算机视觉/深度学习)代码
- unity 常用函数