问题叙述:
五个哲学家坐在一个圆桌上,座子上有五根筷子。每两个哲学家之间有一根筷子。哲学家思考一段时间后就餐,每次准备就餐时,如果左右两边筷子都在则就餐,否则继续思考一段时间。
代码实现
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
//思考函数
void think(int num);
//开始就餐函数
int start(int num);
//结束就餐函数
void end(int num);
//哲学家(一个对应一个线程)
void philosopher(int num);
//线程锁,保证每次只有一个哲学家进行判断是否左右都有筷子
pthread_mutex_t mutex;
//标记五个筷子,0则表示被使用,1则表示未被使用
int cs[5];
int main(void){
//创建五个哲学家
pthread_t p[5];
int i,j;
for(i=0;i<5;i++){
cs[i]=1;
}
printf("chopsticks: %d %d %d %d %d\n",cs[0],cs[1],cs[2],cs[3],cs[4]);
//将线程锁初始化
pthread_mutex_init(&mutex,NULL);
printf("Mutex start!\n");
for(j=0;j<5;j++){
//创建五个线程
i=pthread_create(&p[j],NULL,(void *) philosopher,j);
//成功创建则返回0
if(i!=0){
printf("Create philosopher%d error!\n",j);
exit(1);
}else{
printf("Create philosopher%d succeed!\n",j);
}
}
for(j=0;j<5;j++){
//启动五个线程
pthread_join(p[j],NULL);
}
return 0;
}
void think(int num){
int ThinkTime;
//哲学家思考的时间,时间是一个随机数
ThinkTime=rand()%10;
printf("Philosopher %d start thinking, time: %ds\n",num,ThinkTime);
//哲学家开始思考
sleep(ThinkTime);
}
int start(int num){
int try;
printf("Philosopher %d want to use mutex\n",num);
//尝试上锁,上锁成功则返回0
try=pthread_mutex_trylock(&mutex);
if(0!=try){
//线程锁被其他哲学家占用,就餐失败
printf("Philosopher %d use mutex unsuccessfully!\n",num);
return 2;
}else{
//上锁成功
//左右筷子未被占用,可以就餐
if(cs[num%5]==1&&cs[(num+1)%5]==1){
//占用左右筷子
cs[num%5]=0;
cs[(num+1)%5]=0;
//解锁
pthread_mutex_unlock(&mutex);
return 1;
}else{
//左右筷子被占用,就餐失败
printf("Philosopher%d's chopsticks have been used by others.\n",num);
pthread_mutex_unlock(&mutex);
return 2;
}
}
}
void end(int num){
while(1){
int try;
//就餐结束,尝试占用锁来归还筷子,如果占用失败则一直尝试
try=pthread_mutex_trylock(&mutex);
//占用成功
if(0==try){
//归还筷子
cs[num%5]=1;
cs[(num+1)%5]=1;
//解锁
pthread_mutex_unlock(&mutex);
break;
}
}
}
void philosopher(int num){
//times标记哲学家的就餐次数
int times,a,j;
printf("philosopher %d join!\n",num);
for(times=0;times<5;j=0){
//哲学家开始思考
think(num);
//哲学家思考完准备就餐
a=start(num);
if(a==1){
//哲学家可以就餐
printf("Philosopher %d start eating.\n",num);
//就餐次数加1
times++;
//就餐5秒
sleep(5);
//结束就餐
end(num);
printf("Philosopher %d end eating.\n",num);
}
//如果a不为1则表示哲学家不可以进行就餐,继续思考
}
}
现存问题
- 筷子的占用问题可以使用And信号量的方法来完成,但是这个方法我还没有搞懂,希望可以有大神指教