和尚取水问题

某寺庙中有小和尚、老和尚若干人。庙内有一水缸,由小和尚提水入缸,供老和尚饮用。

水缸可容纳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();
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值