操作系统经典同步问题——读者写者问题

问题描述

有读者写者两组并发进程,共享一个文件,读进程可以同时访问,但写进程不能和其他进程(读写进程都有)同时访问。要求:
1.允许多个读者同时对文件进行读操作
2.只允许一个写者进程写操作
3.任何一个写者在完成写操作前不允许其他读或者写进程工作
4.写者执行写操作前,应该让任何进程都退出

问题分析

  1. 关系分析
    很明显,读者和写者进程是互斥的,写者和写者之间也是互斥的。
    但读者问题比较复杂,因为它需要保证与其他读者进程同步的同时并与读者互斥。

  2. 信号量设置
    实现读者和写者的互斥只需要采用一个互斥信号量rw,而实现写者之间的互斥信号量则用mutex表示.

存有问题的代码

semaphore mutex=1;//用于实现计数保证读者同时访问
semaphore rw=1;//用于控制读者写者互斥访问

Writer(){
	while(1){
		P(rw);
		//writing
		V(rw);
	}
}

Reader(){
	while(1){
		P(rw);
		//reading
		V(rw);
	}
}

很显然,如果采用上述代码,没有办法实现读者可以同时读,随便多一个读者或者写者进程到来都会造成阻塞。
那我们可否考虑一种解决方案,增加一个计数变量,当该进程是第一个读进程时,阻止写进程写,直到最后一个读进程,才允许写进程写。这样的方案是可行的:

semaphore mutex=1;//用于实现计数保证读者同时访问
int count=0;//计数变量
semaphore rw=1;//用于控制读者写者互斥访问

Writer(){
	while(1){
		P(rw);
		//writing
		V(rw);
	}
}

Reader(){
	while(1){
		P(mutex);//互斥访问count
		//如果是第一个读进程
		if(count==0){
			P(rw);//阻止写进程进行,接下来都是读进程的操作
		}
		count++;//表明增加了一个读进程
		V(mutex);
		//reading

		//此处为一个读进程读完
		P(mutex);
		count--;//表明减少了一个读进程
		if(count==0){//如果此时是最后一个进程
			V(rw);//允许写操作进行
		}
		V(mutex);
	}
}

进程饥饿的解释

此时该同步问题能够得以实现,但存在一个进程饥饿的问题,假设存在着源源不断的读进程,那只要不是最后一个读进程,写进程就不能进行,最终会导致饿死。这就是进程饥饿的问题。
那我们可否考虑让写进程先优先执行呢,毕竟从常理上来说,要写完了才能读嘛。
答案当然是肯定的。解决方案如下:
再额外设置一个信号量w用来让写进程优先进行。

semaphore mutex=1;//用于实现计数保证读者同时访问
int count=0;//计数变量
semaphore rw=1;//用于控制读者写者互斥访问
semaphore w=1;//用于实现写优先

Writer(){
	while(1){
		P(w);
		P(rw);
		//writing
		V(rw);
		V(w);
	}
}

Reader(){
	while(1){
		P(w);
		P(mutex);//互斥访问count
		//如果是第一个读进程
		if(count==0){
			P(rw);//阻止写进程进行,接下来都是读进程的操作
		}
		count++;//表明增加了一个读进程
		V(mutex);
		//reading
		
		V(w);
		//此处为一个读进程读完
		P(mutex);
		count--;//表明减少了一个读进程
		if(count==0){//如果此时是最后一个进程
			V(rw);//允许写操作进行
		}
		V(mutex);
	}
}

注意

实际上,上述的所谓写者优先也只是相对而言,要实现真正的写优先,还得查阅别的资料。此处就不说了。
对于这一问题,有一个显著的特征,就是一个互斥访问的计数器count,这样一个计数器变量的互斥访问,能够实现某些进程同步的同时又与其他进程异步的情况,因此当碰到一个不太好解决的互斥问题时,可以考虑用这样的思想解决问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值