操作系统:读者写者问题(C++实现)

2023-12-11 02:20

本文主要是介绍操作系统:读者写者问题(C++实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

读者写者问题描述:

读者只会读取数据,不会修改数据,而写者即可以读也可以修改数据。

  1. 同一时刻,允许多个读者同时读
  2. 没有写者时读者才能读,没有读者时写者才能写
  3. 没有其他写者时,写者才能写

1、读者优先

代码实现:

semaphore wMutex; //写操作的互斥信号量,初始值为1
semaphore rCountMutex; //对读者的互斥修改,初始值为1
int rCount = 0;  //正在进行读操作的读者个数,初始化为0void writer( )
{while(TRUE){P( wMutex); //进入临界区write( );/**进行写操作*/V(wMutex);//进入临界区}
}
void reader( )
{while(TRUE){P(rCountMutex);//进入临界区if ( rCount == 0){P(wMutex);//如果有写者,则阻塞写者}rCount++    //读者计数+1V(rCountMutex );//离开临界区/**进行读操作*/P(rCountMutex);//进入临界区rCount--;//读完数据,准备离开if ( rCount == 0){V( wMutex);//最后一个读者离开了,则唤醒写者}V( rCountMutex ) ;//离开临界区}
}

上面的这种实现,是读者优先的策略,因为只要有读者正在读的状态,后来的读者都可以直接进入,如果读者持续不断进入,则写者就无法得到运行。

2、写者优先

那既然有读者优先策略,自然也有写者优先策略:

  1. 只要有写者准备要写入,写者应尽快执行写操作,后来的读者就必须阻塞;
  2. 如果有写者持续不断写入,则读者就处于饥饿状态,一直无法进行读操作;

代码实现:

semaphore rCountMutex;//控制对Rcount的互斥修改,初始值为1
semaphore rMutex;//控制读者进入的互斥信号量者,初始值为 1semaphore wCountMutex//控制 wCount互斥修改,初始值为1
semaphore wDataMutex//控制写者写操作的互斥信号量,初始值为1int rCount = 0; //正在进行读操作的读者个数,初始化为0
int wCount = 0;//正在进行读操作的写者个数,初始化为0void writer()
{while(TRUE){P(wCountMutex);//进入临界区if ( wCount ==0 ){P( rMutex);1/当第一个写者进入,如果有读者则阻塞读者}wCount++; //写者计数+1V(wCountMutex);//离开临界区P( wDataMutex);//写者写操作之间互斥,进入临界区/**进行写操作*/V(wDataMutex);    //离开临界区P(wCountMutex);    //进入临界区wCount--;    //写完数据,准备离开if (wCount == 0 ){V(rMutex);// 最后一个写者离开了,则唤醒读者}V(wCountMutex);//离开临界区}
}void reader()
{while(TRUE){P(rMutex);P(rCountMutex);//进入临界区if ( rCount == 0){P(wDataMutex);//当第一个读者进入,如果有写者则阻塞写者写操作}rCount++;V(rCountMutex);//离开临界区V(rMutex);/**进行读操作*/P(rCountMutex);//进入临界区rCount--;if (rCount == 0){V(wDataMutex);//当没有读者了,则唤醒阻塞中写者的写操作}v(rCountMutex);//离开临界区}
}

注意,这里rMute的作用,开始有多个读者读数据,它们全部进入读者队列,此时来了一个写者,执行了 P(rMute) 之后,后续的读者由于阻塞在 rMute 上,都不能再进入读者队列,而写者到来,则可以全部进入写者队列,因此保证了写者优先。

同时,第一个写者执行了 P(rMute) 之后,也不能马上开始写,必须等到所有进入读者队列的读者都执行完读操作,通过V(wDataMutex)唤醒写者的写操作。

3、读者写者公平策略

 要求:

  1. 优先级相同;
  2. 写者、读者互斥访问;
  3. 只能一个写者访问临界区;
  4. 可以有多个读者同时访问临界资源;

具体代码实现:

semaphore rCountMutex; //控制对Rcount的互斥修改,初始值为1
semaphore wDataMutex  //控制写者写操作的互斥信号量,初始值为1
semaphore flag;   //用于实现公平竞争,初始值为1
int rCount = 0;   //正在进行读操作的读者个数,初始化为0void writer()
{while(TRUE){P( flag );P(wDataMutex);//写者写操作之间互斥,进入临界区/**进行写操作*/V(wDataMutex); //离开临界区V(flag);}
}void reader( )
{while(TRUE){P(flag);P(rCountMutex);//进入临界区if (rCount==0){P(wDataMutex);//当第一个读者进入,如果有写者则阻塞写者写操作}rCount++;V(rCountMutex);//离开临界区V(flag);/**进行写操作*/P(rCountMutex ); //进入临界区rCount--;if (rCount == 0){V(wDataMutex);//当没有读者了,则唤醒阻塞中写者的写操作}V(rCountMutex); //离开临界区}
}

对比方案一的读者优先策略,可以发现,读者优先中只要后续有读者到达,读者就可以进入读者队列, 而写者必须等待,直到没有读者到达。

没有读者到达会导致读者队列为空,即 rCount==0,此时写者才可以进入临界区执行写操作。

而这里 flag 的作用就是阻止读者的这种特殊权限(特殊权限是只要读者到达,就可以进入读者队列)。

比如:开始来了一些读者读数据,它们全部进入读者队列,此时来了一个写者,执行 P(flag) 操作,使得后续到来的读者都阻塞在 flag 上,不能进入读者队列,这会使得读者队列逐渐为空,即 rCount 减为 0。

这个写者也不能立马开始写(因为此时读者队列不为空),会阻塞在信号量 wDataMutex 上,读者队列中的读者全部读取结束后,最后一个读者进程执行 V(wDataMutex),唤醒刚才的写者,写者则继续开始进行写操作。

而如果是写者先到,然后读者随之而来,那么后面再来的写者程序也会应为读者的P(flag)阻塞再这个信号量之上,带读者读完后再能继续写。

从这两个方面来看确实完成了读者和写者的公平对待。

这篇关于操作系统:读者写者问题(C++实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/479125

相关文章

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间