"读者写者问题"是计算机科学领域中与并发编程相关的一个经典问题。该问题涉及到多个进程或线程在共享数据的环境中的协同操作。具体而言,问题描述了两类角色:读者和写者,它们共享一个数据存储区域(如共享内存或文件)。读者和写者之间存在互斥和同步的关系,以确保在读写过程中不会发生冲突或数据不一致的情况。
读者写者问题的主要目标是在多个读者和写者之间实现合理的并发访问策略,以确保数据的一致性和有效性。
一、基本概念解释
1.互斥访问: 写者在写操作时需要独占访问共享数据,以防止其他写者或读者同时修改数据。
2.写者优先: 如果有写者正在写数据,其他写者和读者需要等待写者完成后才能访问。
3.多个读者同时访问: 多个读者可以同时读取共享数据,读者之间不需要互斥访问。
二、问题描述
三、问题分析
信号量的定义:
semaphore rw = 1; //用于实现对共享文件的互斥访问
int count = 0; //记录当前有几个读进程在访问文件
semaphore mutex = 1; //用于保证对count变量的互斥访问
semaphore w = 1; // 用于实现”写优先“
第一阶段:
首先针对文件的互斥访问,所以加了第一把锁(rw),解决了在进行写操作时不能进行再次的写操作和读操作。
第二阶段:
在阶段一的基础上虽然解决了进行写操作时不能进行读操作或写操作,但是不满足多个进程同时进行读操作。为了解决这一问题从而引入了count信号量,如果是第一个读的程序就对资源上锁,否则就不上锁。但是有一个问题,如果有多个读进程,在第一个读进程还没有上锁之前就切换到了另一个进程进行上锁操作,导致第一个读进程不能进行读操作。所以再定义一个互斥信号量(mutex),对count进行上锁,只有在判断完后是第一个进程,并且对资源进行上锁后才对保护count的锁进行解锁。
第三阶段:
第二阶段后,还存在一个问题,就是如果有源源不断的读操作,那么写操作就会出现饥饿状态。于是还需要一把锁,定义了W互斥信号量进行上锁。这样一来如果现在有一个读进程,然后又来一个写进程和读进程,那么执行完第一个读进程之后,就会执行写进程。
四、问题总结
本篇文章是我在学习完操作系统的读者——写着问题后的总结,在我看来程序都是从最初的有很多Bug,然后才慢慢优化,不断完善的,所以我觉得读者——写者问题也是这一,当一把锁不能满足需求时就再加一把锁。刚开始学习时我也感觉到有很多的锁,并且不明白这些锁的作用。所以在学习完一遍后我就手写了伪代码,用自己的思想去把伪代码写出来。遇到卡顿的地方就好好思考,实在想不出就返回去再看一遍。