题目
有一个仓库存放两种零件A和B,最大库存容量各为m个,有一车间不断取A和B进行装配,每次各取一个。为避免零件锈蚀,遵循先入库先出库原则,有两个供应商分别不断地供应A和B 。为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n(n<m)个时,暂停对数量大的零件进货,集中补充数量少的零件。试用P、V操作正确实现之。
关键句子
- 最大库存容量各为m个;
- 一车间不断取A和B进行装配,每次各取一个;
- 两个供应商分别不断地供应A和B (两供应商之间的互斥);
- 当某种零件的数量比另一种的数量超过n(n<m)个时,暂停对数量大的零件进货,集中补充数量少的零件 (两供应商之间的同步);
同步和互斥
- 两个供应商和车间操作仓库的 互斥;
- 两个供应商之间的变形 同步(数量相差n);
- 两个供应商和车间的 同步(有容量入库,有库存出库);
思路
- 首先明确两个供应商和车间操作仓库是互斥的,所以三个进程的代码中间都是抢夺这个权限的;
int mutex = 1; //操作仓库的权限
PinA(){
P(mutex);
//入库A零件
V(mutex);
}
PinB(){
P(mutex);
//入库B零件
V(mutex);
}
Pout(){
P(mutex);
//出库A和B零件
V(mutex);
}
- 然后先解决车间出库的进程问题。在出库之前,必须要有零件A和零件B;
int countA = m; //A的库存
int countB = m; //B的库存
int mutex = 1; //操作仓库的权限
PinA(){
P(mutex);
//入库A零件
V(mutex);
}
PinB(){
P(mutex);
//入库B零件
V(mutex);
}
Pout(){
P(countA);
P(countB);
P(mutex);
//出库A和B零件
V(mutex);
V(countB);
V(countA);
}
- 因为入库出库之间有一个同步的关系,必须要有位置才能入库,必须要有库存才能出库,所以要用两个变量实现这个同步,一个count不足以解决这个问题;
int emptyA = m; //A的剩余库存容量
int emptyB = m; //B的剩余库存容量
int fullA = 0; //A的库存数量
int fullB = 0; //B的库存数量
int mutex = 1; //操作仓库的权限
PinA(){
P(emptyA);
P(mutex);
//入库A零件;
V(mutex);
V(fullA);
}
PinB(){
P(emptyB);
P(mutex);
//入库A零件;
V(mutex);
V(fullB);
}
Pout(){
P(fullA);
P(fullB);
P(mutex);
//出库A和B零件
V(mutex);
V(emptyB);
V(emptyA);
}
- 最后要解决的就是当某种零件的数量比另一种的数量超过n(n<m)个时,暂停对数量大的零件进货,集中补充数量少的零件这个问题。这里我是上网找资料才知道怎么解决的。这是两供应商之间的一种同步,一种变形的同步
解释(看完代码再看):举个最简单的例子,假如一开始一直都是入库A零件,当入库了n个时,B零件和A零件的数量就相差了n个了,那么Sa=0,供应商A不能参与争夺操作仓库的权限了。
int emptyA = m; //A的剩余库存容量
int emptyB = m; //B的剩余库存容量
int fullA = 0; //A的库存数量
int fullB = 0; //B的库存数量
int Sa = n; //A和B的相差数量
int Sb = n; //Sa和Sb实现AB入库的同步
int mutex = 1; //操作仓库的权限
PinA(){
P(emptyA);
P(Sa);
P(mutex);
//入库A零件;
V(mutex);
V(Sb);
V(fullA);
}
PinB(){
P(emptyB);
P(Sb);
P(mutex);
//入库A零件;
V(mutex);
V(Sa);
V(fullB);
}
Pout(){
P(fullA);
P(fullB);
P(mutex);
//出库A和B零件
V(mutex);
V(emptyB);
V(emptyA);
}
完整代码
int emptyA = m; //A的剩余库存容量
int emptyB = m; //B的剩余库存容量
int fullA = 0; //A的库存数量
int fullB = 0; //B的库存数量
int Sa = n; //A和B的相差数量
int Sb = n; //Sa和Sb实现AB入库的同步
int mutex = 1; //操作仓库的权限
main(){
PinA();
PinB();
Pout();
}
PinA(){
P(emptyA);
P(Sa);
P(mutex);
//入库A零件;
V(mutex);
V(Sb);
V(fullA);
}
PinB(){
P(emptyB);
P(Sb);
P(mutex);
//入库A零件;
V(mutex);
V(Sa);
V(fullB);
}
Pout(){
P(fullA);
P(fullB);
P(mutex);
//出库A和B零件
V(mutex);
V(emptyB);
V(emptyA);
}
总结
- 老师是说做这种题目要先想好信号量和变量,不过我按照老师说的方法的确做不出来,还是要想好几个大概的信号量,再边写边改。