操作系统(二十六)读者写者问题
2.3.9 读者写者问题
读者写者问题是十分经典的进程同步的问题,问题描述如下:读进程与写进程共享文件,但是写进程必须与其他进程互斥发生。
根据以上的题目要求我们可以得出一些互斥关系:写进程与写进程互斥,读进程与写进程互斥
我们可以设置一个互斥信号量rw来实现对互斥信号的共享访问
semaphore rw=1; //用于实现对共享文件的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”}
}reader (){
while(1){P(rw); //读之前“加锁”读文件…V(rw); //读完了“解锁”}
}
但是这样简单的上锁解锁会导致读文件不能同时进行,就像我们进房间,打开门之后接着关上了门,后面的人当然没办法继续进来了。按照日常经验,开门应该有第一个人完成而关门应该有最后一个人完成,于是我们再次引入count计数器,记录正在读的进程数。
semaphore rw=1; //用于实现对共享文件的互斥访问
int count = 0; //记录当前有几个读进程在访问文件
semaphore mutex = 1;//用于保证对count变量的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”}
}reader (){while(1){if(count==0) //由第一个读进程负责P(rw); //读之前“加锁”count++; //访问文件的读进程数+1读文件…count--; //访问文件的读进程数-1if(count==0) //由最后一个读进程负责V(rw); //读完了“解锁”}
}
这样做我们又会发现问题,如果两个读进程同时在count++前访问的话,P(rw)会这执行两次,那么第二个读进程会被阻塞。这是由于对count的检查以及赋值没有一气呵成(缺乏原子性)所以我们需要再来一个变量mutex实现对count互斥访问。
semaphore rw=1; //用于实现对共享文件的互斥访问
int count = 0; //记录当前有几个读进程在访问文件
semaphore mutex = 1;//用于保证对count变量的互斥访问writer (){while(1){P(rw); //写之前“加锁”写文件…V(rw); //写完了“解锁”}
}reader (){while(1){P(mutex); //各读进程互斥访问countif(count==0) //由第一个读进程负责P(rw); //读之前“加锁”count++; //访问文件的读进程数+1V(mutex);读文件…P(mutex); //各读进程互斥访问countcount--; //访问文件的读进程数-1if(count==0) //由最后一个读进程负责V(rw); //读完了“解锁”V(mutex);}
}
但是按照上述的代码来执行的话,写进程的操作总会被读进程的到来而阻塞,可能会导致读进程饥饿,我们再来添加一个互斥信号量w来实现公平读写(先来先服务)
semaphore rw=1; //用于实现对共享文件的互斥访问
int count = 0; //记录当前有几个读进程在访问文件
semaphore mutex = 1; //用于保证对count变量的互斥访问
semaphore w = 1; //用于实现公平writer (){while(1){P(w);P(rw);写文件…V(rw);V(w);}
}reader (){while(1){P(w);P(mutex);if(count==0)P(rw);count++;V(mutex);V(w);读文件…P(mutex);count--;if(count==0)V(rw);V(mutex);}
}
读者-写者问题其核心思想在于设置了一个计数器 count 用来记录当前正在访问共享文件的读进程数。我们可以用count 的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理。
另外,对 count 变量的检查和赋值不能一气呵成导致了一些错误,如果需要实现“一气呵成”,自然应该想到用互斥信号量。
操作系统(二十六)读者写者问题相关推荐
- 模板方法模式 Template method 行为型 设计模式(二十六)
模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...
- OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope
OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...
- 2008R2Win7管理二十六ADRMS客户端使用及侦错
2008R2Win7管理二十六ADRMS客户端使用及侦错 预计我以后都没太多时间专研新技术和写文啦,尽量挤时间吧,有一篇放一篇吧,呵呵 本篇介绍在win7客户端使用adrms来进行权限管理和侦错,在使 ...
- FreeSql (二十六)贪婪加载 Include、IncludeMany、Dto、ToList
贪婪加载顾名思议就是把所有要加载的东西一次性读取. 本节内容为了配合[延时加载]而诞生,贪婪加载和他本该在一起介绍,开发项目的过程中应该双管齐下,才能写出高质量的程序. Dto 映射查询 Select ...
- 零基础带你学习MySQL—foreign key 外键(二十六)
零基础带你学习MySQL-foreign key 外键(二十六) -- 外键演示 -- 创建 主表 my_class CREATE TABLE my_class ( id INT PRIMARY KE ...
- JavaScript学习(二十六)—事件处理程序的添加与删除
JavaScript学习(二十六)-事件处理程序的添加与删除 一.什么是事件? 所谓事件就是指用户或页面自身的某些行为,如点击鼠标,敲击键盘都是属于事件. 二.事件处理程序 当事件被触发时会引起某些程 ...
- Shell脚本学习-阶段二十六-Web服务与端口
文章目录-Shell阶段二十六-端口与服务对照表 前言 端口与Web服务对照表 简介 前言 端口与Web服务对照表 2端口:管理实用程序 3端口:压缩进程 5端口:远程作业登录 7端口:回显 9端口: ...
- 二十六. Python基础(26)--类的内置特殊属性和方法
二十六. Python基础(26)--类的内置特殊属性和方法 ● 知识框架 ● 类的内置方法/魔法方法案例1: 单例设计模式 # 类的魔法方法 # 案例1: 单例设计模式 class Teacher: ...
- GPS从入门到放弃(二十六) --- RTKLIB函数解析
GPS从入门到放弃(二十六) - RTKLIB函数解析 为了贴合这个系列的标题"从入门到放弃",在入门之后现在就要放弃此方向了.虽然感觉遗憾,暂时也没有办法.在此附上此系列最后一篇 ...
- 知识图谱论文阅读(八)【转】推荐系统遇上深度学习(二十六)--知识图谱与推荐系统结合之DKN模型原理及实现
学习的博客: 推荐系统遇上深度学习(二十六)–知识图谱与推荐系统结合之DKN模型原理及实现 知识图谱特征学习的模型分类汇总 知识图谱嵌入(KGE):方法和应用的综述 论文: Knowledge Gra ...
最新文章
- jstl标签: c:Foreach详解
- 【Paper】An Experiment Comparing Double Exponential Smoothing and Kalman Filter-Based Predict
- 使用 [funcref boost::pfr::get] 按索引访问结构体字段的测试程序
- 「Python-Pycharm」zipimport.ZipImportError: can‘t decompress data; zlib not available
- mysql 命令 utf8_Mysql 统一设置utf8字符
- SQL数据库语言基础之SqlServer条件查询、排序数据表、like模糊查询【大总结】
- WPF Image Binding Uri Source 失败解决办法
- NSURLRequest 使用(网络文摘)
- Java常见面试题收集
- ContextCaptureMaster/Smart3D 集群简单配置
- Permute 3.6.4 小巧便捷的多媒体文件格式转换器
- Android事件分发机制综述
- 安卓电子书格式_这几种电子书格式的关系与区别,资深Kindler有必要了解了解 !...
- IP地址中的网络地址和主机地址分别是什么意思
- FastReport动态改变字体颜色
- 种子轮、天使轮等相关知识
- 中青年人脑白质的年龄效应和性别差异:DTI、NODDI 和 q 空间研究
- 推荐《天才在左,疯子在右》
- java使用模板导出Excel表格
- 太厉害了,竟然用 Python 给英语老师开发了个英语作文批改的神器