www.pudn.com > diningphilosopher.zip > diningphilosopher.c


  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
  
#define N        5 
#define LEFT     (i-1)%N 
#define RIGHT    (i+1)%N 
#define THINKING 0 
#define HUNGRY   1 
#define EATING   2  
  
/*重新定义down 和 up函数 */ 
  
#define down(LOCK)   mutex_lock(LOCK) 
#define up(LOCK)     mutex_unlock(LOCK) 
#define semaphore    mutex_t 
  
semaphore mutex;  /*临界区互斥*/  
semaphore s[N];   /*每个哲学家一个信号量*/ 
int state[N];     /*记录每个人状态的数组*/ 
  
/* 
 * 测试,是否相邻的哲学家在吃状态 
 */ 
  
void statecheck(int i) 
{ 
   if ( (state[i] == HUNGRY)&&(state[LEFT] != EATING)&&(state[RIGHT] != EATING) ) {    //如果左右两边的哲学家都不再吃状态 
      state[i] = EATING;                  //则将自已设置为吃状态               
      up(&s[i]);                          //打开互斥锁   
   } 
} 
  
/* 
 * 如是相邻的哲学家没有吃,则正确的取得筷子.  
 */ 
  
void take_forks (int i) 
{ 
   down(&mutex);    //锁上互斥锁 
   state[i] = HUNGRY;    //设置为饿态 
   statecheck(i);        //测试自已是否能正确取得筷子 
   up(&mutex); 
   down(&s[i]); 
} 
  
 
/* 正确的放下筷子. 改变自身状态成为思考状态.  */ 
  
void put_forks (int i) 
{ 
   down(&mutex);            //关上互斥锁 
   state[i] = THINKING;    //设置思考状态 
   statecheck(LEFT);             //查看是否左边的哲学家能进入吃的状 
   statecheck(RIGHT);            //查看是否左边的哲学家能进入吃的状 
   up(&mutex);             //找开互斥锁    
} 
  
/* 
 *思考与吃状态要持续一段时间. 
 */ 
  
void think(int i) 
{ 
   printf("Philosopher %d is thinking...\n", i);  
   sleep(rand()%60); 
} 
  
void eat(int i) 
{ 
   printf("Philosopher %d is eating...\n", i);  
   sleep(rand()%60); 
} 
  
/* 哲学家所要做的事.*/ 
  
void philosopher (void *arg) 
{ 
    int i=(int)arg; 
    while (1) {    //哲学家永远处于这种状态 
      think(i);    //想 
      take_forks(i); //拿筷子 
      eat(i);    //拿到筷子后开始吃 
      put_forks(i);    //正确放下筷子 
   } 
} 
  
int main ()  
{ 
   pthread_t phil[N]; 
   int i; 
   struct timeval tp; 
   struct timezone tz; 
  
   gettimeofday(&tp,&tz); 
   srand(tp.tv_sec);//产生随机种子数 
  
   pthread_mutex_init(&mutex,NULL);//初始化互斥锁 
  
   for (i=0; i<=N-1; i++) { 
        pthread_create(&phil[i],NULL,philosopher,i);//创建五个线程,但是这儿的i上会出现一个类型转换的警告,不过不影响程序的执行 
   } 
  
    pthread_join(phil[0],NULL);//最后等待线程0的结束,由于线程零不会结束,所以将会进入永远等待状态 
 
    return 0; 
}