读者-写者问题(读者优先、写者优先、公平竞争)

读者-写者问题改进

一、问题(读者优先)

教材中提供的读者-写者问题的解决方案存在读者优先问题,即当有一个读进程比较活跃时,随后而来的读进程都将被允许访问资源。这样,会导致写进程可能长时间等待。而这种情况往往与实际应用需求相背。请认真分析、研究读者-写者问题,给出对读者和写者都较为公平的同步解决方案。

教材方案(读者优先):

semaphore rmutex = 1, wmutex = 1;
int readcount = 0;
void Reader(){
	while(1){
		wait(rmutex);
		if(readcount==0) wait(wmutex);
		readcount++;
		signal(rmutex);
		...
		perform read operation;
		...
		wait(rmutex);
		readcount--;
		if(readcount==0) signial(wmutex);
		signal(rmutex);
	}
}
void Writer(){
	while(1){
		wait(wmutex);
		...
		perform write operation;
		...
		signal(wmutex);
	}
}

二、分析

教材中规定: 写者、读者互斥访问文件资源,只要有读者还占有资源,就不允许写者进入。

此时就出现了问题,当一直有读者或多个读者轮流长时间占据资源,写者会长时间等待,无法获得资源。

上述方法就是读者优先

三、改进方案

1.公平竞争

在教材方法中,一旦读者获得资源,wmutex就会一直小于1,直到所有读者进程结束为止,写者甚至没有竞争资源的机会。

那么,可以就再添加一个信号量,给写者竞争的机会。

如果写者抢到资源,就不能再有其他读者新的读者阅读。接下来只要等待还在阅读的读者全部结束,写者就可以拿到资源。

semaphore rmutex = 1, wmutex = 1, w = 1;
int readcount = 0;
void Reader(){
	while(1){
		wait(w);
		wait(rmutex);
		if(readcount==0) wait(wmutex);
		readcount++;
		signal(rmutex);
		signal(w);
		...
		perform read operation;
		...
		wait(rmutex);
		readcount--;
		if(readcount==0) signial(wmutex);
		signal(rmutex);
	}
}
void Writer(){
	while(1){
		wait(w);
		wait(wmutex);
		...
		perform write operation;
		...
		signal(wmutex);
		signal(w);
	}
}

2.写者优先

由上述两个问题,可以想到,当存在多个写者时,也可以使用写者优先。

同读者优先,只需在写者占有资源后,不允许读者进入,代码基本一致,但需要调整信号量位置来避免死锁。

添加信号量 w_cs : 保证临界区的资源只能有一个写者修改,并实现了读者执行时写者等待。

semaphore rmutex = 1, wmutex = 1, w = 1, w_cs = 1;
int readcount = 0, writecount = 0;
void Reader(){
	while(1){
		wait(w);
		wait(rmutex);
		if(readcount==0) wait(w_cs);
		readcount++;
		signal(rmutex);
		signal(w);
		...
		perform read operation;
		...
		wait(rmutex);
		readcount--;
		if(readcount==0) signial(w_cs);
		signal(rmutex);
	}
}
void Writer(){
	while(1){
		wait(wmutex);
		if(writecount==0) wait(w);
		writecount++;
		signal(wmutex);
		
		wait(w_cs)
		...
		perform write operation;
		...
		signal(w_cs)
		
		wait(wmutex);
		writecount--;
		if(readcount==0) signial(w);
		signal(wmutex);
	}
}

写者优先优化:

如果在写者执行时,有多个读者进入,可能会出现多个读者等待的情况。例如,当第一个读者signal(w)时,第二个读者或者更多的读者此时会和写者同时处于wait(w)的状态,写者无法跳过该长队列,需要和其他读者抢资源,这不符合写者优先。

可以添加一个信号量 q ,写在读者的wait(w)之前。这样只有一个读者可以在wait(w)前排队,其他必须在wait(q)前排队,这样可以让写者优先抢到资源,满足了写者优先。

semaphore rmutex = 1, wmutex = 1, w = 1, w_cs = 1, q = 1;
int readcount = 0, writecount = 0;
void Reader(){
	while(1){
		wait(q);
		wait(w);
		wait(rmutex);
		if(readcount==0) wait(w_cs);
		readcount++;
		signal(rmutex);
		signal(w);
		signal(q);
		...
		perform read operation;
		...
		wait(rmutex);
		readcount--;
		if(readcount==0) signial(w_cs);
		signal(rmutex);
	}
}
void Writer(){
	...
}

参考博客:

读者写者问题(超级详细的分析读者优先,读写平等,写者优先)_Rqff的博客-CSDN博客_读者优先的读者写者问题

读者写者问题(读者优先,写者优先 ,读写公平)_骐骥一跃,不能十步;驽马十驾,功在不舍。-CSDN博客_读者写者问题

  • 16
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值