PV操作系列--读者写者问题

问题描述

有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:
(1) 任意多个读进程可以同时读这个文件;
(2) 一次只有一个写进程可以往文件中写;
(3) 如果一个写进程正在进行操作,禁止任何读进程度文件。

读优先

一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。

readcount  //读者计数器
var rwmutex, rmutex = 1, 1int readcount = 0; 
cobegin 
	procedure reader_i            procedure Writer_j  // i,j = 1,2,….
	while true then               while true then
	begin                         begin
	P(rmutex);                    P(rwmutex); 
	                              写更新;
	Readcount + +;                V(rwmutex); 
	if (readcount = = 1)          end
		P(rwmutex);  // rwmutex 大于0时,自动从此处运行
	V(rmutex);
	读数据; 
	P(rmutex); 
	Readcount - -;
	if (readcount = = 0) 
		V(rwmutex);
	V(rmutex);
end
Coend

读优先–代码分析

读进程
  • readcount 表示读进程数
  • rmutex 是对于计数器readcount操作的互斥信号量,rwmutex表示是否允许写的信号量
  • P(rmutex) 表示对每次有一个读者要进行读操作,要先对readcount 共享变量互斥操作,然后判断当前是否是第一名读者,如果是第一名读者,那么接下来将判断rwmutex信号量得出此时是否有作者在临界区(有的话,阻塞读进程;无,阻塞写进程)
  • V(rmutex)表示结束对readcount共享信号量的互斥访问
  • 读者读完后,又开始对readcount共享信号量的互斥访问,此时需要判断readcount是否为0,代表最后一个人离开读进程区,从而判断是否有写进程,if yes,唤醒其中一个写进程到临界区
写进程
  • 如果有读进程,写进程阻塞
  • 写进程完毕,判断是否有阻塞的读进程,if yes,唤醒其中一个读进程进入临界区。执行完V(rwmutex) 一方面相当于释放了写信号量,另一方面会自动唤醒读进程

写优先

1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写操作,也不允许读写同时进行《rwmutex只有一份》)
3)写者优先于读者(一方面,一旦有写者(正在运行),则后续读者必须等待,另一方面V(rwmutex)唤醒时 优先考虑写者,其次才是读者)
假设读者数是固定的,算法如下:

rwmutex:用于写者与其他读者/写者互斥的访问共享数据
rmutex:该信号量初始值设为10,表示最多允许10个读者进程同时进行读操作
var rwmutex, rmutex: semaphore := 1, 10;

cobegin 
procedure reader_i          procedure Writer_j
begin	                    begin // j = 1,2,….
P(rwmutex);                 P(rwmutex);
P(rmutex);                  for (i = 1;i <= 10;i + +) P(rmutex);
//读数据
V(rwmutex);                 //禁止新读者,并等待已进入的读者退出读进程
							// 写更新;
V(rmutex);                  for (i = 1;i <= 10;i + +) V(rmutex);
end                         //恢复允许rmutex值为10,唤醒读进程
                            v(rwmutex)
							end

Coend 

写优先–代码分析

读进程
  • 先检查P(rwmutex)确保:先有写操作时,读进程阻塞
  • 先释放V(rwmutex) 一方面为了确保后续的读操作可以正常运行,另一方面此时如果有正在等待的写操作,优先唤醒写操作
  • 读操作先运行就只有一种情况,就是必须在写操作之前申请rwmutex
写进程
  • for (i = 1;i <= 10;i + +) P(rmutex); //一旦申请了写信号量,直接提前占用10个读信号量
  • 写操作结束后,再通过循环释放读信号量
  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值