操作系统自学(十三)生产者消费者问题以及多生产者多消费者问题

生产者消费者问题

系统中有一组生产者进程和消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品使用
(产品为某种数据)

生产者消费者共享一个初始为空 大小为n的缓冲区
只有缓冲区没满的时候 生产者才能将产品放入缓冲区,否则必须等待
(同步关系 缓冲区满的时候,生产者要等待消费者取走产品)
只有缓冲区不空的时候 消费者才能从缓冲区中取出产品否则必须等待
同步关系 缓冲区空的时候 消费者必须等待生产者放入产品)

在这里插入图片描述

缓冲区是临界资源 所以各进程必须互斥的访问

我们可以使用P,V操作实现生产者和消费者进程的功能
由之前的学习我们知道 信号量机制可实现互斥,同步,对一类系统资源的申请和释放
互斥 设置初值为1的互斥信号量
**同步 设置初值为0的同步信号量 实现一前一后 **
设置一个信号量 初值为资源的数量(本质上也是同步问题 若无空闲资源,则申请资源的进程需要等待其他进程释放资源之后才能执行)

然后我们用代码来实现一下
在实现之前 我们再来捋一下
生产者工作的前提:消费者没有工作 空闲缓冲区数量大于0
消费者工作的前提:生产者没有工作 产品剩余数量大于0

满足上边两条即可

semaphore mutex = 1;//互斥信号量 实现对缓冲区的互斥访问
semaphore empty = n;//同步信号量 表示空闲缓冲区的数量
semaphore full = 0;//同步信号量 表示产品数量 也是非空缓冲区的数量

producer(){
	//生产者	
	while(1){
	生产一个产品
	P(empty);
	P(mutex);
	把产品放入缓存区
	V(mutex);
	V(full);
	}
} 
consumer(){
	//消费者	
	while(1){
	P(full);
	P(mutex);
	从缓冲区取出一个产品
	V(mutex);
	V(empty);
	使用产品
	}
}

特别注意 其中的P语句顺序不能颠倒顺序 否则会出问题 但是V语句可以交换顺序

生产者等待消费者释放空闲缓冲区,消费者等待生产者释放临界区
生产者和消费者循环等待对方唤醒自己 出现死锁
实现互斥的P操作一定要在实现同步的P之后

生产者消费者问题是一个互斥同步的综合问题
**实现一前一后 需要前V后P **

最后还是要强调一点 就是:实现互斥和实现同步的先后顺序

多生产者多消费者问题

我们思考一个问题
桌子上只有一个盘子,每次只可以向其中放入一个水果,爸爸专门向盘子中放入苹果,妈妈专门向盘子中放入橘子
儿子专门吃盘子中的橘子,女儿专门吃盘子中的苹果,只有盘子里边为空的时候,爸爸妈妈才能向其中放入水果
而且仅当盘子中有水果的时候 儿女才能拿走水果
在这里插入图片描述
然后我们先梳理关系
互斥关系
对盘子(缓冲区)的访问需要互斥进行

同步关系(一前一后)
爸爸在盘子里放入苹果 必须在女儿拿取苹果之前
妈妈在盘子里放入橘子 必须在儿子拿取橘子之前
只有盘子为空的时候 父母才可以放入水果

通过之前的学习 我们可以想到互斥:在临界区前后分别PV 同步 前V后P

semaphore mutex=1;//实现互斥访问盘子(缓冲区)
semaphore apple=0;//盘子中有几个苹果
semaphore orange=0;//盘子中有几个橘子
semaphore plate=1;//盘子中还可以放几个水果

dad(){
准备一个苹果
P(mutex);//实现互斥访问
P(plate);//能放入的水果数--
放入盘子一个苹果
V(apple);//放入一个苹果
V(mutex);
}
mom(){
准备一个橘子
P(mutex);
P(plate);
放入盘子一个橘子
V(orange);
V(mutex);
}
daughter(){
P(apple);//拿走苹果的前提是有苹果
P(mutex);
从盘子拿走一个苹果
V(plate);//能放入的水果数++
V(mutex);
吃苹果
}

son(){
P(orange);
P(mutex);
从盘子拿走一个橘子
V(plate);
V(mutex);
吃橘子
}

上述就是多生产者多消费者的问题的思路
所谓多不是生产者消费者个数多 是指生产者消费者种类多

如果我们仔细看代码并思考的话 我们可能发现如果没有实现互斥的变量mutex的话
程序是可以正常执行的

这是因为这个问题中的plate的初始值为1 如果初始值大于一
可能出现两个进程同时访问缓冲区的情况 导致写入的数据相互覆盖的情况

所以 如果缓冲区大小大于1 就必须设置一个互斥信号量mutex来保证互斥访问缓冲区

还有一点细心的朋友们可能发现了在儿子和女儿的代码中 互斥P操作在同步P操作后 这是避免发生死锁
P(orange);
P(mutex);

这个还是挺容易理解的吧 就是父母放水果和儿女拿水果不矛盾

这类问题我们要从事件角度考虑
盘子变空事件 到 放入水果事件
盘子变空事件可以由儿子引发也可能是女儿引发
放入水果事件 可能是父亲引发 也可能是母亲引发

以上就是两类生产者消费者问题 希望对大家有所帮助

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于哪个视频是最好的Linux操作系统自学教程,这个问题没有一个确定的答案,因为每个人的学习方式和需求不同。以下是几个可以考虑的方面: 1. 网络口碑和用户评价:在选择Linux操作系统自学教程视频时,重要的是查看其他用户的评价和评论。可以通过搜索引擎、IT技术论坛或社交媒体上的讨论来了解不同视频的受欢迎程度和用户反馈。 2. 视频内容:确定视频内容是否覆盖了你感兴趣的主题和技能水平,确保视频涵盖了Linux操作系统的基本概念、常用命令、文件系统、网络配置以及系统管理等关键知识点。 3. 教学风格:不同的讲师有不同的教学风格,你可以通过观看视频片段来了解他们的教学方法和语言表达是否适合你的学习风格。 4. 更新频率和内容质量:确定视频是最近发布的并且信息是最新的,因为Linux操作系统在不断发展,所以更新的资源对于学习来说是很重要的。 5. 适合初学者的教程:如果你是初学者,可以选择那些针对初学者提供基础知识和详细解释的教程。这些教程通常会有更多的细节和步骤,以帮助你更好地理解和掌握Linux操作系统。 总之,通过自我评估和参考他人评价,你可以找到最适合你的Linux操作系统自学教程视频。与此同时,不要依赖于单一的资源,多样化的学习方式可以帮助你更全面地理解和掌握Linux操作系统

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值