多生产者,多消费者问题
桌子上有一个盘子,每一只能放入一个水果,爸爸只向盘子中放苹果,妈妈只向盘子中放橘子,儿子只吃盘中的橘子,女儿只吃盘中的苹果,盘子空时才可放入水果,有水果时才可取出水果。用PV操作实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | semaphore mutex=1; //实现互斥的访问盘子(缓冲区) semaphore apple=0; //盘子中有几个苹果 semaphore orange=0; //盘子中有几个橘子 semaphore palte=1; //盘子中还可以放多少个水果 dad(){ while (1){ 准备一个苹果; P(plate); P(mutex); 把苹果放入盘子; V(mutex); V(apple); } } mom(){ while (1){ 准备一个橘子; P(plate); P(mutex); 把橘子放入盘子; V(mutex); V(orange); } } daughter(){ while (1){ P(apple); P(mutex); 从盘子中取出苹果; V(mutex); V(plate); 吃掉苹果; } } son(){ while (1){ P(orange); P(mutex); 从盘子中取出橘子; V(mutex); V(plate); 吃掉橘子; } } |
在本例中哟与缓冲区(盘子)大小为1,在任何时刻,apple,orange,plate三个同步信号量中最多只有一个是1,因此在任何时刻最多只有一个进程的P操作不会被阻塞,并顺利地进入临界区。所以本题中也可以不设专门的互斥变量mutex.要对具体问题具体分析,加上互斥信号量保证个进程一定会互斥的访问缓冲区,但需要注意的是,实现互斥的p操作一定要在实现同步的P操作之后,否则会引起“死锁”。
解决“多生产者—多消费者问题”的关键在于理清复杂的同步关系。
在分析同步问题(一前一后问题)的时候不能从单个进程行为角度来分析,要把“一前一后”发生的事看作是两种“事件”的前后关系。
比如,如果从单个进程行为的角度来考虑的话,会有以下定论:
若盘子里有苹果,一定女儿取走苹果后父亲或母亲才能放入水果;
若盘子里有橘子,一定儿子取走水果后父亲或母亲才能放入水果;
这么看要设置四个同步信号量分别实现这四个“一前一后”的关系
正确的分析方法应该从“事件”的角度来考虑,把“进程行为的前后关系”抽象为“一对事件的前后关系”
盘子变空——>放入水果事件。盘子变空事件可由儿子或女儿触发,放水果事件可能是父亲也可能是母亲执行,这样的话,就可以只用一个同步信号量解决了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端