信号量机制——读者-写者问题

问题描述

一个共享数据区,有若干个进程负责对其进行读入工作,若干个进程负责对其进行写入工作。

  • 允许多个进程同时读数据
  • 互斥读数据
  • 若有进程写数据,不允许读者读数据

对照生活中的购票系统:

  • 一个联网售票系统,数据的查询和更新非 常频繁,不可避免会出现多个进程试图查询或修 改(读/写)其中某一条数据的情形。多个进程同 时读一条记录是可以的,但如果一个进程正在更 新数据库中的某条记录,则所有其他进程都不能访问(读或写)该记录,否则可能会将同一个座 位销售多次

解决办法

读者优先

基本描述

一旦有读者正在读数据,允许多个读者同时进入读数据,只有当全部读者退出,才允许写者进入写数据。

满足条件:

  • 对于读者

    • 没有读者和写者,直接读数据
    • 有写者等待,其他读者正在读,越过写者,直接进入读数据
    • 有写者写数据,新读者等待
  • 对于写者
    • 无读者,新写者直接写
    • 有读者,新写者等待
    • 有写者,新写者等待
问题存在:写者操作被长期挂起,无法操作——写者饥饿
实现思路

设置一个共享变量和两个信号集

  • 共享变量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
分析与总结
  1. 对于计数器的访问,一定是一个一个的访问,一个一个的数,互斥访问计数器。
  2. 互斥访问计数器,wait(rmutex)还可以阻塞后面读进程,如果当前的读进程因为有写进程陷入了阻塞,后面的读进程进不了计数器,就陷入了阻塞。如果没有写进程,还可以阻塞后来的写进程
  3. 同时通过绕过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
分析与总结
  1. 互斥访问计数器的时候必须要是一个同一个资源信号量,在进入时没有释放,就不能退出,在退出没有释放时,就不能进入。防止出现同时写入和退出,造成判断条件的混乱
  2. 通过将p操作有不同的进程操作,实现进程之间的相互控制,比如上述,通过写者线程控制读者线程,实现了写者优先。

信号量机制——读者-写者问题相关推荐

  1. 同步机制—读者写者问题

    [实验目的] 理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法. [实验内容] 在windows或者linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程,其中既有读者 ...

  2. 读者写者问题详解 操作系统

    2.16 读者写者问题 抽象解释 多个进程访问一个共享的数据区 读者(读进程)只能读数据,写者(写进程)只能写数据 适用于数据库.文件.内存.寄存器等数据区的访问模型 如12306购票系统,由于用户量 ...

  3. 操作系统中读者——写者问题的分析

    操作系统中读者--写者问题的分析 Analysis of readerwriter problem in operating system 摘要:本篇文章就操作系统中读者--写者问题进行利用记录型信号 ...

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

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

  5. 操作系统【信号量集机制、“读者-写者”问题】

    0.信号量机制应用引导篇.flv 1.信号量集机制解决读写问题深入分析.flv   03:00 2."读者-写者"问题之"顺序执行".flv   07:32 3 ...

  6. 信号量机制实现读者写者问题(思路剖析+Java代码实现+验证)

    写在前面: Java中: 我们用这样的代码新建一个信号量:Semaphore mutex = new Semaphore(1); P操作(wait)的代码为:mutex.acquire(); V操作( ...

  7. 锁机制:读者写者问题 Linux C

    最近碰到一些锁机制的问题,想起大三的时候做过的一个小课设,记录复习一下. 问题描述: 一个数据文件可以被多个进程共享,其中,有些进程要求读(reader进程),而另一些进程要求对数据进行写或修改(wr ...

  8. 用信号量和读写锁解决读者写者问题

    用信号量和读写锁解决读者写者问题 参考文章: (1)用信号量和读写锁解决读者写者问题 (2)https://www.cnblogs.com/xybaby/p/6559212.html 备忘一下.

  9. 信号量 读者写者问题

    写了两个小程序验证 1 /*  2  *   读者写者问题,读者优先  3  *   <<操作系统-内核与设计原理>> p183,p184  4  *   有读者在读那么后来的 ...

最新文章

  1. ios 登录 java 后台,IOS苹果登录sign in with apple后端校验
  2. 11gOCP 1z0-052 :2013-09-11 MGR_ROLE role........................................................A66
  3. 如何制作计算机启动盘,一款U盘启动盘制作小工具
  4. Hibernate与MyBatis对比
  5. 导出mysql excel数据字典_mysql导出 Excel数据字典(全)
  6. ajax跨浏览器初始化,使用Ajax的jQuery localStorage的跨浏览器
  7. cisco路由器故障判断及排除 计算机管理与维护
  8. MySQL数据库专家分享资深DBA经验
  9. 计算机网络相关的知识,计算机网络相关知识整理
  10. Mangos某人经验
  11. 51.php-fpm的pool 慢日志 open_basedir 进程管理
  12. 智能时尚:人工智能在时尚服装行业的应用综述 | 580+参考文献
  13. 重读Ardupilot中stabilize model+MAVLINK解包过程
  14. 与激光雷达死磕的毫米波雷达,除了无人驾驶还有更多归宿
  15. 车载无线自组织网络的介质访问控制协议研究
  16. 前端开发Vue项目实战:电商后台管理系统(八)------ 订单管理模块
  17. 多媒体制作技术心得体会_多媒体技术学习心得体会总结
  18. 元柚话TK:海外抖音TikTok+独立站如何搭建?
  19. [安装fastfds中的nginx执行make命令报错]src/core/ngx_murmurhash.c:37:11: error
  20. 五、DML(数据操纵语句)

热门文章

  1. python django前端重构_Django学习笔记(11)——开发图书管理页面
  2. matlab程序循环,matlab循环程序只得到一个结果
  3. 【AI CLUB】机器学习基础丨01
  4. 漫画 | 99%的程序员都在第6层!
  5. 微信公众号线上和线下增粉秘籍:
  6. 数字源表搭建集成电路教学测试平台
  7. 记一次微信小程序直播对接
  8. win10Ie重置.html默认应用设置,解决win10中edge提示“若要更改默认应用程序请转到设置”的教程...
  9. 创新实训——飞讯(八)
  10. C语言编程规范 — 头文件、函数