Linux作业:研究哲学家就餐问题解决方案,选定其中一种编码实现,哲学家就餐用进程或线程实现均可。
这里选用进程实现,可以自己更改哲学家人数,这里是6个。
思路
首先尝试获取左边的筷子,获取成功则尝试获取右边的筷子,全获取,则进餐,进餐后释放左右筷子;若尝试获取右筷子失败,则可继续尝试,若尝试次数达到5次,则放弃左边筷子,并重新开始获取右边筷子。若尝试左边筷子次数达到10,则表示无法获取筷子,线程退出。
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#define phi_NUM 6
#define left (id+1)%phi_NUM
#define right id
//创建6个互斥锁
pthread_mutex_t chopstic[phi_NUM];
char phi[phi_NUM][20] = {"小瓜","谷子","风风","哒滴","队长","花花"};
void *func(void *arg){
int id = *(int*)arg;
int try_count_l = 0;
int try_count_r = 0;
printf("%s is thinking ?_?\n",phi[id]);
while(try_count_l<10){
if(pthread_mutex_trylock(&chopstic[left]) == 0){
printf("%s got left-%d\n",phi[id],left);
while(try_count_r<5){
if(pthread_mutex_trylock(&chopstic[right]) ==0){
printf("%s is eating *@*\n",phi[id]);
//随机休眠,表示在吃
sleep(rand()%4);
//释放互斥锁
pthread_mutex_unlock(&chopstic[right]);
pthread_mutex_unlock(&chopstic[left]);
printf("%s finish eating ^_^\n",phi[id]);
try_count_l = 0;
try_count_r = 0;
//pthread_exit(NULL);
}
usleep(1000000);
try_count_r++;
}
pthread_mutex_unlock(&chopstic[left]);
printf("%s gave up left-%d T_T\n",phi[id],left);
}
usleep(10000000);
try_count_l++;
}
printf("%s couldn't start eating!\n",phi[id]);
pthread_exit(NULL);
}
int main(void){
pthread_t philosopher[phi_NUM];
int philosopherID[phi_NUM];
//设置随机数生成器的种子,以便产生不同的随机数序列
srand(time(NULL));
int i;
//初始化
for(i=0;i<phi_NUM;i++){
// 初始化锁
pthread_mutex_init(&chopstic[i],NULL);
}
for(i=0;i<phi_NUM;i++){
// 创建5个线程
philosopherID[i] = i;
pthread_create(philosopher+i,NULL,func,(void*)&philosopherID[i]);
}
//回收子线程
for(i = 0;i<phi_NUM;i++){
pthread_join(philosopher[i],NULL);
}
//销毁互斥锁
for(i = 0;i<phi_NUM;i++){
pthread_mutex_destroy(&chopstic[i]);
}
//退出
pthread_exit(NULL);
}