信号量机制——读者-写者问题
信号量机制——读者-写者问题
问题描述
一个共享数据区,有若干个进程负责对其进行读入工作,若干个进程负责对其进行写入工作。
- 允许多个进程同时读数据
- 互斥读数据
- 若有进程写数据,不允许读者读数据
对照生活中的购票系统:
- 一个联网售票系统,数据的查询和更新非 常频繁,不可避免会出现多个进程试图查询或修 改(读/写)其中某一条数据的情形。多个进程同 时读一条记录是可以的,但如果一个进程正在更 新数据库中的某条记录,则所有其他进程都不能访问(读或写)该记录,否则可能会将同一个座 位销售多次
解决办法
读者优先
基本描述
一旦有读者正在读数据,允许多个读者同时进入读数据,只有当全部读者退出,才允许写者进入写数据。
满足条件:
- 对于读者
- 没有读者和写者,直接读数据
- 有写者等待,其他读者正在读,越过写者,直接进入读数据
- 有写者写数据,新读者等待
- 对于写者
- 无读者,新写者直接写
- 有读者,新写者等待
- 有写者,新写者等待
问题存在:写者操作被长期挂起,无法操作——写者饥饿
实现思路
设置一个共享变量和两个信号集
- 共享变量reader:记录当前正在读数据集的读进程数,初值为0
- 读互斥信号量rmutex:表示读进程互斥访问共享变量reader,初值为1,互斥信号
- 写互斥信号量wmutex:表示写进程与其他进程(读写进程)互斥访问数据集,初值为1.互斥信号量
流程图
注:
- 虽然是实现了多个读者进程同时读取了数据集的操作,是因为通过if判断语句绕过了p操作,直接访问数据。
- 我们平常所说的互斥访问是用P(S)和V(S)操作将临界资源区包裹起来,才实现互斥访问,临界资源区本身就没有实现互斥访问的性质,是通过进入区和退出区联合实现的,如果能够绕过,就可以不用互斥访问。
伪代码实现
program readers_writers;
const reader:integer(:= 1); // 用于统计读者的个数
var wmutex,rmutex:semophore(:= 1); // 初始化信号量
procedure reader;
begin repeat;wait(rmetex); // 开始对读者进程进行计数,互斥访问计数器reader = reader + 1; //有一个读者进入计数器,那就+1if reader == 1 then wait(wmetex);//如果是第一个进程,判断是否有写进程在临界区,若有,都进程等待,若无,写进程等待signal(rmutex);//结束对计数器互斥访问<读取数据>;wait(rmutex);//开始对共享变量计数器进行互斥访问reader = reader - 1;//一个进程读完了,读进程数-1if reader == 0 then signal(wmutex);//如果是最有一个进程,那就判断是否有写进程进入了临界区,若有,唤醒一个写进程进入临界区signal(rmutex);//结束对reader计数器的互斥访问until false;
end;
procedure writers
begin repeat;wait(wmutex);//写进程互斥访问读写操作;若有读进程,就陷入阻塞,若是没有读进程,那就执行<写入数据>;signal(wmutex);//写进程完成操作,如果有读进程陷入阻塞,那就唤醒until false;
end;
beginparbegin;writers;readers;parend;
end
分析与总结
- 对于计数器的访问,一定是一个一个的访问,一个一个的数,互斥访问计数器。
- 互斥访问计数器,wait(rmutex)还可以阻塞后面读进程,如果当前的读进程因为有写进程陷入了阻塞,后面的读进程进不了计数器,就陷入了阻塞。如果没有写进程,还可以阻塞后来的写进程
- 同时通过绕过wait(S)操作,就不存在互斥访问了;绕过进入区,随便访问临界资源
写者优先
方法描述
只要有一个写者申请写数据,就不允许新的读者绕过写者,进去读数据。写着只需要等待其前面的写者写完就可以写了。
问题:降低并发度,系统的性能较差
实现思路
在读者优先的基础上,增加排队信号量read,读写进程在每一次操作前都要等待read信号量
流程图
注:写者有一个自己的计数器,一旦有一个写者进来,就会打开读者进入计数器的p操作,使读者不能进计数器,在计数器外陷入阻塞,然后再读写临界区门口陷入阻塞,等待。
伪代码
program readers_writers;
const reader,writer:integer(:= 1); // 用于统计读者的个数
var x,ywmutex,rmutex:semophore(:= 1); // 初始化信号量
procedure reader;
begin repeat;wait(rmetex); //实现写者优先wait(x);// 开始对读者进程进行计数,互斥访问计数器reader = reader + 1; //有一个读者进入计数器,那就+1if reader == 1 then wait(wmetex);//如果是第一个进程,判断是否有写进程在临界区,若有,都进程等待,若无,写进程等待signal(x);//结束对计数器互斥访问signal(rmutex);<读取数据>;wait(x);//开始对共享变量计数器进行互斥访问reader = reader - 1;//一个进程读完了,读进程数-1if reader == 0 then signal(wmutex);//如果是最有一个进程,那就判断是否有写进程进入了临界区,若有,唤醒一个写进程进入临界区signal(x);//结束对reader计数器的互斥访问until false;
end;
procedure writers
begin repeat;wait(y);writer = writer + 1;if writer == 1 then wait(rmutex);//通过写者进程来控制读者进程signal(y)wait(wmutex);//写进程互斥访问读写操作;若有读进程,就陷入阻塞,若是没有读进程,那就执行<写入数据>;signal(wmutex);//写进程完成操作,如果有读进程陷入阻塞,那就唤醒wait(y);writer = writer - 1;if writer == 0 then signal(rmutex);signal(y)until false;
end;
beginparbegin;writers;readers;parend;
end
分析与总结
- 互斥访问计数器的时候必须要是一个同一个资源信号量,在进入时没有释放,就不能退出,在退出没有释放时,就不能进入。防止出现同时写入和退出,造成判断条件的混乱
- 通过将p操作有不同的进程操作,实现进程之间的相互控制,比如上述,通过写者线程控制读者线程,实现了写者优先。
信号量机制——读者-写者问题相关推荐
- 同步机制—读者写者问题
[实验目的] 理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法. [实验内容] 在windows或者linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程,其中既有读者 ...
- 读者写者问题详解 操作系统
2.16 读者写者问题 抽象解释 多个进程访问一个共享的数据区 读者(读进程)只能读数据,写者(写进程)只能写数据 适用于数据库.文件.内存.寄存器等数据区的访问模型 如12306购票系统,由于用户量 ...
- 操作系统中读者——写者问题的分析
操作系统中读者--写者问题的分析 Analysis of readerwriter problem in operating system 摘要:本篇文章就操作系统中读者--写者问题进行利用记录型信号 ...
- 操作系统——读者写者问题(写者优先)
阅读前提醒:本文代码为伪代码,仅供理解! 马上就要被关得精神失常了,也许这是我的最后一条博客了吧--() 啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈水文来咯!!!!! ...
- 操作系统【信号量集机制、“读者-写者”问题】
0.信号量机制应用引导篇.flv 1.信号量集机制解决读写问题深入分析.flv 03:00 2."读者-写者"问题之"顺序执行".flv 07:32 3 ...
- 信号量机制实现读者写者问题(思路剖析+Java代码实现+验证)
写在前面: Java中: 我们用这样的代码新建一个信号量:Semaphore mutex = new Semaphore(1); P操作(wait)的代码为:mutex.acquire(); V操作( ...
- 锁机制:读者写者问题 Linux C
最近碰到一些锁机制的问题,想起大三的时候做过的一个小课设,记录复习一下. 问题描述: 一个数据文件可以被多个进程共享,其中,有些进程要求读(reader进程),而另一些进程要求对数据进行写或修改(wr ...
- 用信号量和读写锁解决读者写者问题
用信号量和读写锁解决读者写者问题 参考文章: (1)用信号量和读写锁解决读者写者问题 (2)https://www.cnblogs.com/xybaby/p/6559212.html 备忘一下.
- 信号量 读者写者问题
写了两个小程序验证 1 /* 2 * 读者写者问题,读者优先 3 * <<操作系统-内核与设计原理>> p183,p184 4 * 有读者在读那么后来的 ...
最新文章
- 如何快速部署国人开源的 Java 博客系统 Tale
- linux 逻辑卷扩展
- Tensorflow学习—— Estimator简介
- Java 多态(一)
- 三天内出现多次晃动,华强北最高楼今日起已被封闭了
- pytorch torch.save
- python是什么课程-python是什么(python是什么课程)
- 经典排序算法(十九)--Flash Sort
- 我在软件协会修WiFi
- 【图像检测】基于matlab GUI比值+归一化+相关系数遥感图像【含Matlab源码 737期】
- 如何连接到sqlplus
- 恶意代码分析实战 lab1-4
- PHP中smart原则,制定目标时的SMART原则不包括什么
- 汉字大全20000个字_男生秀恩爱的说说简短八字 小情话大全暖心8个字
- 西门子博途TIA PORTAL硬件目录中无法找到CPU的固件版本时,如何下载项目数据?
- 黄河科技学院计算机等级考试成绩查询,全国计算机等级考试成绩查询汇总
- python数据分析之pandas数据合并
- apollo学习之---(17)commen-math学习
- Creo 4.0 软件安装教程
- 车牌识别之字符切割2
热门文章
- 山水郎_斗笠_day40
- 章鱼网络进展月报 | 2022.5.1-5.31
- Stack Overflow 2022 开发者调查报告出炉啦
- IntelliJ IDEA安装破解教程
- Windows中通过虚拟机搭建iPhone开发环境
- Point Density-Aware Voxels for LiDAR 3D Object Detection 论文笔记
- 车牌识别 opencv linux,Edison + opencv + webcam 实现车牌识别
- 弱网下的极限实时视频通信
- PS利用调整图层只需两步为偏黄肤色MM调出水嫩效果
- Python面试基础篇 - 50道经典面试题(附答案及多种解答)