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

2023-11-18

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

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……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统——读者写者问题(写者优先) 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • 使用 Enumerable.OfType() 或 LINQ 查找特定类型的所有子控件

    Existed MyControl1 Controls OfType
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何通过 JsonConvert.DeserializeObject 在动态 JSON 中使用 null 条件运算符

    我正在使用 Newtonsoft 反序列化已知的 JSON 对象并从中检索一些值 如果存在 关键在于对象结构可能会不断变化 因此我使用动态来遍历结构并检索值 由于对象结构不断变化 我使用 null 条件运算符来遍历 JSON 代码看起来像这
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • Spark 源码阅读一-启动脚本

    Spark Complile Help Links Because spark 1 5 need maven version 3 3 3 so i track the branch 1 4 git branch a git checkout
  • Day13 static-静态变量

    一 static 1 关于JavaBean类中的成员变量 public class Student private String name private int age private String gender 新增老师姓名 publi
  • 网页访问计数器 html,网页计数器(访问量)

    1 PHP实现网站访问量计数器 思路 用户向服务器发出访问请求 服务器读取访问次数文件 1 向客户端返回 服务器保存新的浏览次数 新用户访问 重复即可 解决方案 主要算法 1 数据文件 counter dat 2 读出数据文件 打开文件 如
  • Python Web:Flask异步执行任务

    Flask 是 Python 中有名的轻量级同步 web 框架 在一些开发中 可能会遇到需要长时间处理的任务 此时就需要使用异步的方式来实现 让长时间任务在后台运行 先将本次请求的响应状态返回给前端 不让前端界面 卡顿 当异步任务处理好后
  • jQuery empty() vs remove()

    https stackoverflow com questions 3090662 jquery empty vs remove http www cnblogs com yeer archive 2009 06 10 1500682 ht
  • JavaSE复习笔记

    第一章 Java概述 一 计算机语言 机器语言 汇编语言 高级语言 二 跨平台原理 Java可以在一处开发到处运行 即在一类操作系统上开发的程序 可以在任何操作系统上运行 不同的操作系统有不同的JVM java是运行在JVM上 从而实现了跨
  • win7系统打开定位服务器地址,win7 定位服务器地址

    win7 定位服务器地址 内容精选 换一换 您可以通过云日志服务 查看访问七层共享型负载均衡请求的详细日志记录 分析负载均衡的响应状态码 快速定位异常的后端服务器 您已经创建了七层负载均衡 您已经开通了云日志服务 登录管理控制台 在管理控制
  • 函数式组件与类组件有何不同?

    与React类组件相比 React函数式组件究竟有何不同 在过去一段时间里 典型的回答是类组件提供了更多的特性 比如state 当有了Hooks后 答案就不再是这样了 或许你曾听过它们中的某一个在性能上的表现优于另一个 那是哪一个 很多此类
  • MultipartFile实现文件上传和下载(Springboot)

    MultipartFile是SpringMVC提供简化上传操作的工具类 在不使用框架之前 都是使用原生的HttpServletRequest来接收上传的数据 文件是以二进制流传递到后端的 然后需要我们自己转换为File类 使用了Multip
  • 计算机专业选修课怎么选比较好,大一选修课选什么好 大学选修课推荐

    大学之于高中最大的不同点除了越来越多的自由时间以外 大学有各种各样的选修课供我们选择 在专业课之余 还可以选择其他自己感兴趣的学科进行学习 同时也能给自己增加一项技能 大学热门选修课 1 职场礼仪 礼仪是永远不会过时的 它是一个人的修养素质
  • 语法6:raise - 触发异常

    目录 1 基础格式 2 raise 单独语句 3 raise class 4 raise instance 5 raise from 6 try raise 实现循环跳出
  • JDK的命令行工具——修改中

    目录 一 jps 虚拟机进程状况工具 二 jstat 虚拟机统计信息监视工具 三 jinfo java配置信息工具 四 jmap java内存映像工具 五 jhat 虚拟机堆转储快照分析工具 仅做了解即可 六 jstack java堆栈跟踪
  • 以太坊私有网络的设置与体验

    记录一下搭建一个以太坊私有网络环境的过程 方便以后的开发 我这里采用的是Geth客户端 在geth ethereum org网站上有详细的文档介绍 这里主要是按照官网的教程来操作 安装 我是Ubuntu的环境 执行以下命令来安装 sudo
  • 使用hydra进行FTP认证破解

    hydra入门 hydra是什么 hydra的安装 hydra的基本使用 熟悉常见协议 HTTP协议 FTP协议 SSH协议 Telnet协议 熟悉hydra的参数 基本参数 高级参数 使用方法 使用hydra进行HTTP认证破解 HTTP
  • 搭建机器人电控系统——通信协议——串口通信USART/UART、RS232、RS485及其实例

    通信协议 串口通信详解 IIC通信详解 SPI通信详解 CAN通信详解 文章目录 通信协议 什么是串口 串口分类 USART UART RS232 RS485的区别 串口协议原理 传输协议 需要定义的参数 发送函数USART SendDat
  • Java是一门什么语言?

    个人理解 Java代码需要先编译成class 然后交给JVM执行 而JVM在执行class代码时是解释执行的 所以Java不是一门单纯的编译型或解释型语言 它是一门混合型语言 它是集编译型语言和解释型语言的优势于一身 即执行速度较快 只需编
  • 微调(fine-tuning)

    微调 fine tuing 是一种迁移学习 transfer learning 方法 在迁移学习过程中 预训练的模型的权重会根据新数据进行训练和调整
  • Python工程师面试必备25条知识点

    1 到底什么是Python 你可以在回答中与其他技术进行对比 Python是一种解释型语言 与C语言和C的衍生语言不同 Python代码在运行之前不需要编译 其他解释型语言还包括PHP和Ruby Python是动态类型语言 指的是你在声明变
  • Vue实现高德地图信息窗

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

    阅读前提醒 本文代码为伪代码 仅供理解 马上就要被关得精神失常了 也许这是我的最后一条博客了吧 啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈水文来咯 1 什么是读者写者问题 一个数据文件或记录可被多个进程共享