⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diningphilosopher.c

📁 哲学家就餐问题算法实现
💻 C
字号:
 
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
 
#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;
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -