用c语言、条件变量解决哲学家进餐问题。我的解决思路:以左叉子和右叉子是否同时存在作为条件来判断哲学家是否可以吃饭。
1.把五把叉子的状态初始化为TRUE(存在)。cond数组保存的是五个哲学家的条件变量。
2.testfork函数中(forkstatus[left]==TRUE&&forkstatus[right]==TRUE)是哲学家是否可以吃饭的条件,不满足条件就进入等待;满足条件就改变叉子的状态(forkstatus[left]=FALSE;forkstatus[right]=FALSE;//拿起左叉子和右叉子)。
3.eating函数就不解释了。
4.returnforks函数表示放下叉子。放下叉子后并唤醒他的相邻哲学家。
存在的问题:运行后发现每次只有两个哲学家参与吃饭。
请指出我的问题。
代码如下:
#include
#include
#include
#include
#include
#include
#define NUM 5
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond[NUM]={
PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,
PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,
PTHREAD_COND_INITIALIZER
};
#define FALSE -1
#define TRUE 1
volatile int forkstatus[5]={TRUE,TRUE,TRUE,TRUE,TRUE};
void test_forks(int id)
{
int left=id%NUM;//左叉子的编号
int right=(id+1)%NUM;//右叉子的编号
pthread_mutex_lock(&mutex);
while(!(forkstatus[left]==TRUE&&forkstatus[right]==TRUE))//条件是左叉子和右叉子同时存在
{
pthread_cond_wait(&cond[id],&mutex);
}
assert(forkstatus[left]==TRUE&&forkstatus[right]==TRUE);
forkstatus[left]=FALSE;
forkstatus[right]=FALSE;//拿起左叉子和右叉子
assert(forkstatus[left]==FALSE&&forkstatus[right]==FALSE);
pthread_mutex_unlock(&mutex);
}
void returnforks(int id)
{
int left=id%NUM;//左叉子的编号
int right=(id+1)%NUM;//右叉子的编号
int l=(id-1+NUM)%NUM;//左哲学家id
int r=(id+1)%NUM;//右哲学家id
pthread_mutex_lock(&mutex);//在互斥锁的保护下把叉子放好
forkstatus[left]=TRUE;
forkstatus[right]=TRUE;
pthread_cond_signal(&cond[l]);
pthread_cond_signal(&cond[r]);
pthread_mutex_unlock(&mutex);
}
void eating(int id)
{
printf("哲学家%d正在吃饭\n",id);
sleep(id);
printf("哲学家%d吃完饭了\n",id);
}
void *philosopher(void *i)
{
int id=*((int *)i);//哲学家id
while(1)
{
test_forks(id);
eating(id);
returnforks(id);
}
}
int main(int argc,char** argv)
{
int i;
pthread_t tid[NUM];
for(i=0;iNULL,philosopher,&i);
}
getchar();
return 0;
}