Linux编程:进程同步问题之哲学家就餐问题

7 篇文章 0 订阅
7 篇文章 0 订阅

一、哲学家就餐问题描述

如下图,5个哲学家用一生的时间吃饭和思考。他们共用一张圆桌,每人都有一张椅子,桌上放着5支筷子。每个哲学家感到饥饿时,会试图拿起左右的两只筷子,每位哲学家每次只能拿起一只筷子。当每位哲学家同时有两支筷子的时候,他可以吃饭。当他吃完后,他会放下筷子,并开始思考。
我们需要保证不会出现哲学家饿死的情况发生。
这里写图片描述

二、解决方法

文章将采用以下两种方法解决哲学家就餐问题

  • 要求每位哲学家同时拿起两只筷子。
  • 要求座位号为奇数的哲学家先拿左手的筷子,偶数的哲学家先拿右手的筷子。

三、代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#define Phi_Number 5

pthread_mutex_t chopstick[5] ;  

void *solve1(void *arg)  
{  
    	int phi = *(int *)arg;  
    	int left,right; 
    	switch (phi)
	{  
		case 1:  
		    left = 5;  
		    right = 1;  
		    break;  
		case 2:  
		    left = 1;  
		    right = 2;  
		    break;  
		case 3:  
		    left = 2;  
		    right = 3;  
		    break;  
		case 4:  
		    left = 3;  
		    right = 4;  
		    break;  
		case 5:  
		    left = 4;  
		    right = 5;  
		    break; 
	}  
	   
	while(1)
	{  
		printf("Philosopher %d is thiking !\n",phi);
		sleep(1); // thinking
		pthread_mutex_lock(&chopstick[left]); // Ruquest left chopstick		
		time_t timep11;
		time (&timep11);
		printf("Philosopher %d takes left chopstick %d at %s",phi,left,asctime(gmtime(&timep11)));
		
		if (pthread_mutex_trylock(&chopstick[right]))//return 0 if success
		{    
		    	pthread_mutex_unlock(&chopstick[left]); // Release left chopstick 
			printf("Philosopher %d release left chopstick %d\n", phi, left);  
		    	continue;  
		}  
		time_t timep1;
		time (&timep1);
		printf("Philosopher %d takes right chopstick %d at %s", phi, right,asctime(gmtime(&timep1))); 
		printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);  
		sleep(3); // eating
		pthread_mutex_unlock(&chopstick[left]); // Release left chopstick 
		printf("Philosopher %d release left chopstick %d\n", phi, left);  
		pthread_mutex_unlock(&chopstick[right]); //  Release right chopstick 
		printf("Philosopher %d release right chopstick %d\n", phi, right);  
	  	pthread_exit(0);

    	}  
}  

void *solve2(void *arg)  
{  
    	int phi = *(int *)arg;  
    	int left,right; 
    	switch (phi)
	{  
		case 1:  
		    left = 5;  
		    right = 1;  
		    break;  
		case 2:  
		    left = 1;  
		    right = 2;  
		    break;  
		case 3:  
		    left = 2;  
		    right = 3;  
		    break;  
		case 4:  
		    left = 3;  
		    right = 4;  
		    break;  
		case 5:  
		    left = 4;  
		    right = 5;  
		    break; 
	}  
	while(1)
	{  
		printf("Philosopher %d is thiking !\n",phi);
		sleep(1); // thinking
		
		if(phi%2 != 0)//Odd Number
		{
			pthread_mutex_lock(&chopstick[left]); // Ruquest left chopstick
			time_t timep11;
			time (&timep11);
			printf("Philosopher %d takes left chopstick %d at %s",phi,left,asctime(gmtime(&timep11)));
			if (pthread_mutex_trylock(&chopstick[right]))//return 0 if success
			{    
			    	pthread_mutex_unlock(&chopstick[left]); // Release left chopstick 
				printf("Philosopher %d release left chopstick %d\n", phi, left);  
			    	continue;  
			}  

			time_t timep1;
			time (&timep1);
			printf("Philosopher %d takes right chopstick %d at %s\n",phi,right,asctime(gmtime(&timep11)));
			printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);  
			sleep(3); // eating
			pthread_mutex_unlock(&chopstick[left]); // Release left chopstick 
			printf("Philosopher %d release left chopstick %d\n", phi, left);  
			pthread_mutex_unlock(&chopstick[right]); //  Release right chopstick 
			printf("Philosopher %d release right chopstick %d\n", phi, right);  
		  	pthread_exit(0);	
		}
		else{
			pthread_mutex_lock(&chopstick[right]); // Ruquest left chopstick
			time_t timep1;
			time (&timep1);
			printf("Philosopher %d takes right chopstick %d at %s",phi,right,asctime(gmtime(&timep1)));
			
			if (pthread_mutex_trylock(&chopstick[left]))//return 0 if success
			{    
			    	pthread_mutex_unlock(&chopstick[right]); // Release left chopstick 
				printf("Philosopher %d release right chopstick %d\n", phi, right);  
			    	continue;  
			}  
			time_t timep11;
			time (&timep11);
			printf("Philosopher %d takes left chopstick %d at %s\n",phi,left,asctime(gmtime(&timep11)));
			printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);  
			sleep(3); // eating
			pthread_mutex_unlock(&chopstick[right]); // Release left chopstick 
			printf("Philosopher %d release right chopstick %d\n", phi, right);  
			pthread_mutex_unlock(&chopstick[left]); //  Release right chopstick 
			printf("Philosopher %d release left chopstick %d\n", phi, left);  
		  	pthread_exit(0);	
		}
		

    	}  
}  

int main()
{  
	int choose;
	printf("Enter 1 for solve1,2 for solve2:\n");
	scanf("%d",&choose);
	pthread_t Philos[Phi_Number];
	  	int ret[Phi_Number];
	    	int i,j,k,m;  
	   	for (i = 0; i < Phi_Number; i++){
			pthread_mutex_init(&chopstick[i],NULL); 
		} 
		int a[5] = {1,2,3,4,5};
	if(choose == 1)
	{
	    	
		ret[0] = pthread_create(&Philos[0],NULL,&solve1, &a[0]); 
		ret[1] = pthread_create(&Philos[1],NULL,&solve1, &a[1]); 
		ret[2] = pthread_create(&Philos[2],NULL,&solve1, &a[2]); 
		ret[3] = pthread_create(&Philos[3],NULL,&solve1, &a[3]); 
		ret[4] = pthread_create(&Philos[4],NULL,&solve1, &a[4]); 
		//sleep(1); //指线程被调用时,占着CPU不工作,其他线程无法进入
	}
	if(choose == 2)
	{
		ret[0] = pthread_create(&Philos[0],NULL,&solve2, &a[0]); 
		ret[1] = pthread_create(&Philos[1],NULL,&solve2, &a[1]); 
		ret[2] = pthread_create(&Philos[2],NULL,&solve2, &a[2]); 
		ret[3] = pthread_create(&Philos[3],NULL,&solve2, &a[3]); 
		ret[4] = pthread_create(&Philos[4],NULL,&solve2, &a[4]); 
		//sleep(1); //指线程被调用时,占着CPU不工作,其他线程无法进入
	}
	pthread_join(Philos[0],NULL);  
	pthread_join(Philos[1],NULL);
	pthread_join(Philos[2],NULL);
	pthread_join(Philos[3],NULL);
	pthread_join(Philos[4],NULL);
	
    	return 0;  
}

四、运行结果

1.采用解决方案1

这里写图片描述
这里写图片描述

2.采用解决方案2

这里写图片描述
这里写图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值