哲学家就餐问题

原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子会更合理,所以:一个哲学家需要两根筷子才能吃饭。

现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。

假设哲学家的编号是A、B、C、D、E,筷子编号是1、2、3、4、5,哲学家和筷子围成一圈如下图所示:

解法:

至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。将room作为信号量,只允许4个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入餐厅的哲学家进入room的等待队列

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<process.h>
#include<windows.h>
int ROOM=4;
int chopstick[5]={1,1,1,1,1};
void return_chopstick(int i){
	chopstick[i]=1;
}
void take_chopstick(int i){
	while(1){
		if(chopstick[i]!=0){
			chopstick[i]=0;
			break;
		}else{
			Sleep(200);
		}
	}
}
void think(int i){
	int num;
	srand((int)time(NULL));
	num=rand()/50+1;
	printf("哲学家%d 正在思考......\n\n",i);
	Sleep(10*num);
	printf("哲学家%d 思考完毕......\n\n",i);
}
void eat(int i){
	int num;
	srand((int)time(NULL));
	num=rand()/50+1;
	ROOM-=1;
	while(1){
		if(ROOM!=0){
	        take_chopstick(i-1);
	        take_chopstick(i%5);
 	        printf("哲学家%d 正在吃饭中......\n\n",i);
            Sleep(10*num);
	        printf("哲学家%d 吃饭完毕......\n\n",i);
	        return_chopstick(i-1);
	        return_chopstick(i%5);
	        ROOM+=1;
			break;
		}else{
			printf("哲学家%d等待中......\n\n",i);
			Sleep(200);
		}
	}
}

void philosopher1(void *p) {
	while(1){
	think(1);
	eat(1);
	}
}
void philosopher2(void *p) {
	while(1){
	think(2);
	eat(2);
	}
}
void philosopher3(void *p) {
	while(1){
	think(3);
	eat(3);
	}
}
void philosopher4(void *p) {
	while(1){
	think(4);
	eat(4);
	}
}
void philosopher5(void *p) {
	while(1){
	think(5);
	eat(5);
	}
}
int main(){
	int n;
	printf("           哲学家就餐模拟系统          \n\n");
	printf("#######################################\n");
	printf("#                                     #\n");
	printf("#                                     #\n");
	printf("#           1、开始模拟               #\n");
	printf("#                                     #\n");
	printf("#                                     #\n");
	printf("#           2、退出系统               #\n");
	printf("#                                     #\n");
	printf("#                                     #\n");
	printf("#                                     #\n");
	printf("#######################################\n");
	scanf("%d",&n);
	if(n==1){
        _beginthread(philosopher1, 0, NULL);
		_beginthread(philosopher2, 0, NULL);
		_beginthread(philosopher3, 0, NULL);
		_beginthread(philosopher4, 0, NULL);
		_beginthread(philosopher5, 0, NULL);



		_endthread();
		_endthread();
		_endthread();
		_endthread();
		_endthread();
	}else{
		exit(0);
	}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值