桌上有一空盘,最多允许存放相同的两只水果……
题目:桌上有一空盘,最多允许存放相同的两只水果。爸爸每次可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。
试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。
重点分析爸爸的进程:
- 最多只能放两个水果
- 放苹果与放桔子互斥,但是多个放苹果操作之间不互斥
- 实现放苹果和放桔子间在放水果时互斥,设置一个互斥信号量orangemutex。
- 设置一个整型变量applecount表示正在放苹果的数量。
- 由于只要有一个放苹果操作在,便不允许放桔子操作,因此仅当applecount=0,表示尚无放苹果操作,才需要去看是否需要放桔子,也就是p(orangemutex)。
- 若p(orangemutex)操作成功,放苹果操作便可执行,并且applecount+1。
- 同理,仅当放苹果操作执行了applecount减1操作直到为0时,表示没有在放苹果,才可执行打开放桔子的锁,也就是v(orange)。
- 又因为applecount是可以被多个放苹果操作访问,因此也应该为它设置一个互斥信号量applemutex
- 同理放桔子与放苹果互斥,多个放桔子操作之间不互斥
以下为我基于上面逻辑的伪代码,还未考虑周全是否会有死锁情况。
semaphore apple=0;//女儿吃苹果信号
orange=0;//儿子吃桔子信号
fruit=2;//盘子空信号为2(限定最多放两个水果)
//以下为放水果时,放苹果和放桔子互斥信号量
applemutex=1;
orangemutex=1;
int applecount=0;//正在放的苹果数量
int orangecount=0;//正在放的桔子数量
void Father(){
do{
if(想放苹果){
p(applemutex);//能否操作盘子中苹果信号量
p(fruit);//先看水果数量是否超出2个
if (applecount == 0) p(orangemutex);//假如在盘子的苹果为0,才去看需不需要放桔子
applecount++;//在盘子的苹果数量+1
v(applemutex);
放苹果;
v(apple);//女儿吃苹果信号量+1
}
if(想放桔子){
p(orangemutex);//能否操作盘子中桔子信号量
p(fruit);//先看水果数量是否超出2个
if (orangecount == 0) p(applemutex);//假如在盘子的桔子为0,才去看需不需要放苹果
orangecount++;//在盘子的苹果数量+1
v(orangemutex);
放桔子;
v(orange);//儿子吃桔子信号量+1
}
}while(true)
}
void Son(){
do{
p(orange);
吃橘子;
v(fruit);
p(orangemutex);
orangecount--; //在盘子中的桔子数量-1
if (orangecount == 0) v(applemutex);
v(orangemutex);
}while(true);
}
void Daugther(){
do{
p(apple);
吃苹果;
v(fruit);
p(applemutex);
applecount--; //在盘子中的苹果数量-1
if (applecount == 0) v(orangemutex);
v(applemutex);
}while(true);
}
void main(){
do{
Father();
Son();
Daugther();
}while(true)
}