操作系统:2.3.5经典同步问题(1)——生产者消费者问题,多生产者多消费者问题

1. 生产者——消费者问题

问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。

问题分析

1. 分析关系

  1. 同步关系:在这里插入图片描述

  2. 互斥关系:
    在这里插入图片描述

2. 整理思路

  1. 同步关系的P、V操作:
    在这里插入图片描述
  2. 互斥关系的P、V操作:

3. 信号量初值设置

  1. 同步信号量:
    信号量full用于记录当前缓冲池中的“满”缓冲区数,初值为0
    信号量empty用于记录当前缓冲池中的“空”缓冲区数,初值为n
  2. 互斥信号量:
    信号量mutex作为互斥信号量,用于控制互斥访问缓冲池,互斥信号量初值为1;

代码

semaphore mutex=l;					//临界区互斥信号量
semaphore einpty=n;					//空闲缓冲区
semaphore full=0;					//缓冲区初始化为空

producer(){							//生产者进程
	while(1){
		produce an item in nextp;	//生产数据
		P (empty);(要用什么,P—下)	//获取空缓冲区单元
		P (mutex);(互斥夹紧)			//进入临界区
		add nextp to buffer;(行为)	//将数据放入缓冲区
		V (mutex);(互斥夹紧)			//离开临界区,释放互斥信号量
		V(full);(提供什么,V—下)		//满缓冲区数加1
	}
}


consumer(){							//消费者进程
	while (1){
		P(full);					//获取满缓冲区单元
		P(mutex);					//进入临界区
		remove an item from buffer;	//从缓冲区中取出数据
		V(mutex);					//离开临界区,释放互斥信号量
		V(empty);					//空缓冲区数加1
		consume the item;			//消费数据
	}
}

同步和互斥的顺序能否调换顺序?

在这里插入图片描述
类比:
在这里插入图片描述

2. 多生产者——消费者问题

问题描述:桌子上有一个盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈才可向盘子中放一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取岀。

问题分析

1. 分析关系

  1. 同步关系
    在这里插入图片描述
  2. 互斥关系
    在这里插入图片描述
    这里有4个进程,实际上可抽象为两个生产者和两个消费者被连接到大小为1的缓冲区上。

2. 信号量设置

  1. 同步信号量
    信号量apple表示盘子中是否有苹果,初值为0表示盘子为空,不许取,apple=1表示可以取。
    信号量orange表示盘子中是否有橘子,初值为0表示盘子为空,不许取,orange=1表示可以取。
  2. 互斥信号量
    信号量plate,表示是否允许向盘子放入水果,初值为1表示允许放入,且只允许放入一个。

代码

加互斥信号量的代码(推荐)

semaphore plate=1,apple=0,orange=0;

dad(){									//父亲进程
	while(1){
		prepare an apple;
		P(plate);						//互斥向盘中取、放水果
	P(mutex); 
		put the apple on the plate;		//向盘中放苹果
	V(mutex);
		V(apple);						//允许取苹果
	}
}

mom(){									//母亲进程
	while(1){
		prepare an orange;
		P(plate);						//互斥向盘中取、放水果
	P(mutex);
		put the orange on the plate;	//向盘中放橘子
	V(mutex);
		V(orange);						//允许取橘子
	}
}


son () {								//儿子进程
	while(1){
		P (orange);						//互斥向盘中取橘子
	P(mutex);
		take an orange from the plate;
	V(mutex);
		V (plate);						//允许向盘中取、放水果
		eat the orange;
	}
}

daughter (){							//女儿进程
	while (1){
		P (apple);						//互斥向盘中取苹果
	P(mutex);
		take an apple from the plate;
	V(mutex);
		V (plate);						//允许向盘中取、放水果
		eat the apple;
	}
}

不加上互斥信号量的代码

semaphore plate=1,apple=0,orange=0;

dad(){									//父亲进程
	while(1){
		prepare an apple;
		P(plate);						//互斥向盘中取、放水果
		put the apple on the plate;		//向盘中放苹果
		V(apple);						//允许取苹果
	}
}

mom(){									//母亲进程
	while(1){
		prepare an orange;
		P(plate);						//互斥向盘中取、放水果
		put the orange on the plate;	//向盘中放橘子
		V(orange);						//允许取橘子
	}
}


son () {								//儿子进程
	while(1){
		P (orange);						//互斥向盘中取橘子
		take an orange from the plate;
		V (plate);						//允许向盘中取、放水果
		eat the orange;
	}
}

daughter (){							//女儿进程
	while (1){
		P (apple);						//互斥向盘中取苹果
		take an apple from the plate;
		V (plate);						//允许向盘中取、放水果
		eat the apple;
	}
}

在这里插入图片描述

参考资料

《王道:23操作系统考研复习指导》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值