某寺庙中有小和尚、老和尚若干人。庙内有一水缸,由小和尚提水入缸,供老和尚饮用。
水缸可容纳30桶水,每次入水、取水仅为1桶,不可同时进行。
水取自同一水井,水井路窄,每次只能容纳一个水桶取水,设水桶个数为5个。
和尚挑水问题就是使用某种机制,能够使得若干名老和尚可以顺利地喝到水,
若干名小和尚之间能够有条不紊地往水缸中入水。
在程序中使用随机数函数模拟子进程交互执行。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
/*
某寺庙中有小和尚、老和尚若干人。庙内有一水缸,由小和尚提水入缸,供老和尚饮用。
水缸可容纳30桶水,每次入水、取水仅为1桶,不可同时进行。
水取自同一水井,水井路窄,每次只能容纳一个水桶取水,设水桶个数为5个。
和尚挑水问题就是使用某种机制,能够使得若干名老和尚可以顺利地喝到水,
若干名小和尚之间能够有条不紊地往水缸中入水。
*/
#define USE 1
#define FREE 0
#define sleepTime 2
int sleeptime = 10;
int tong = 5;
int tongMax = 5;
int tongMin = 0;
int gang = 0;
int gangMax = 30;
int gangMin = 0;
int jingAndGangUse = 0; // 0 = 未使用, 1 = 使用
int old = 10; // 老和尚人数
int oldMax = 10;
int oldMin = 0;
int little = 10; // 小和尚人数
int littleMax = 10;
int littleMin = 0;
int P(int signal){
return (signal--);
}
int V(int signal){
return (signal++);
}
/**
取水函数(假设取水和放水同时完成)
水缸到井之间只有一条路可走,如果同时允许取水、放水同时进行的话,
取水的必定会在单行道之间某处相撞。
所以应假设水缸和井会同时占用。
1.判断是否有人可以取水
2.判断水桶是否够用
3.判断是否有人占用水缸
*/
int getWater(){
if(little == littleMin){
puts("无人取水,老和尚要死啦~!");
return 0;
}else{
if(tong == tongMin){
puts("水桶不够用了,老和尚要死啦~!");
return 0;
}else{
if(jingAndGangUse == USE){
puts("水缸被占用了,老和尚要死啦~!");
return 0;
}else{
jingAndGangUse = USE;
little = P(little);
tong = P(tong);
puts("小和尚取水中...");
gang++;
puts("水取回来了,小和尚要死啦~!");
if(gang >= gangMax){
gang = gangMax;
puts("水缸满了,老和尚们快来喝水啊~!");
}else{
printf("现在水缸中还有%d桶水\n", gang);
}
tong = V(tong);
little = V(little);
jingAndGangUse = FREE;
return 1;
}
}
}
}
/**
喝水函数
老和尚只需判断
1.判断是否有老和尚要喝水(似乎不需要)
2.判断是否有和尚占用水缸
3.判断水缸中是否有水
*/
int drink(){
if(jingAndGangUse == USE){
puts("水缸被占用了,老和尚要死啦~!");
return 0;
}else{
if(gang == gangMin){
puts("水缸没水了,老和尚要死啦~!");
return 0;
}else{
jingAndGangUse = USE;
puts("老和尚来喝水啦~!");
gang--;
printf("现在水缸中还有%d桶水\n", gang);
jingAndGangUse = FREE;
return 1;
}
}
}
int main(){
srand((unsigned int)time(NULL));
int ran;
for(int i = 0; i < 30; i++){
ran = rand()%2;
if(ran == 0){
getWater();
}
if(ran == 1){
drink();
}
}
}