多生产者,多消费者问题
桌子上有一个盘子,每一只能放入一个水果,爸爸只向盘子中放苹果,妈妈只向盘子中放橘子,儿子只吃盘中的橘子,女儿只吃盘中的苹果,盘子空时才可放入水果,有水果时才可取出水果。用PV操作实现。
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操作之后,否则会引起“死锁”。
解决“多生产者—多消费者问题”的关键在于理清复杂的同步关系。
在分析同步问题(一前一后问题)的时候不能从单个进程行为角度来分析,要把“一前一后”发生的事看作是两种“事件”的前后关系。
比如,如果从单个进程行为的角度来考虑的话,会有以下定论:
若盘子里有苹果,一定女儿取走苹果后父亲或母亲才能放入水果;
若盘子里有橘子,一定儿子取走水果后父亲或母亲才能放入水果;
这么看要设置四个同步信号量分别实现这四个“一前一后”的关系
正确的分析方法应该从“事件”的角度来考虑,把“进程行为的前后关系”抽象为“一对事件的前后关系”
盘子变空——>放入水果事件。盘子变空事件可由儿子或女儿触发,放水果事件可能是父亲也可能是母亲执行,这样的话,就可以只用一个同步信号量解决了。

浙公网安备 33010602011771号