哲学家吃饭问题

来源:互联网 发布:天元围棋频道 网络电视 编辑:程序博客网 时间:2024/04/27 14:58

[code]

/*欢迎转载交流,如果转载请注明作者和出处,谢谢合作。
 *
 *设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,
 *但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿
 *时才试图分两次从两边拿起筷子就餐。
 *条件:
 *1)拿到两只筷子时哲学家才开始吃饭。
 *2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子。
 *3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子。
 *要求:
 *1)描述一 个保证不会出现两个邻座同时要求吃饭的通信算法。
 *2)描述一个即没有两个邻座同时吃饭,有没有饿死(永远拿不到筷子)的算法
 *主要算法实现:
 *1) 使奇数项的哲学家从左手先拿筷子,然后再拿右手的筷子。
 *   偶数项的哲学家就先拿右手的,再拿左手的。
 *作者:bilicon
 *修改时间:2006.5.12
 */

 

#include <stdio.h>
#include <stdlib.h>
#define people   5
#define meat     10 //肉块的数量

 


static int Tman[people];
int n = 1;    //定义n为共吃肉的数量

/////////////////////定义一些需要跟哲学家对应的数组///////////////////////
static int Thinking[people];  //第n个哲学家在思考。如果为1就是真,0就假s
static int Eating[people];    //第n个哲学家在吃。1为真,0为假
static int EatTimeAll[people];
static int EatTime[people];
static int MeatNo[people];

 

int getkey(int i)
{
 //key();
 if(i!=1)
 {
  if(i%2 != 0)         //奇数就从左手开始拿筷子,然后再到右手。
  {
   if(Tman[i-1] == 0)   //i-1为第i个哲学家的左边的筷子0表示该筷子可用,1表示正在被用
   {
    Tman[i-1] = 1;
    if(Tman[i] == 0)
    {
     Tman[i] = 1;
     return 1;
    }
    else
    {
     Tman[i-1] = 0;
     return 0;
 
    }
   }
   else
   {

    return 0;
 
   }
  }
  else     //偶数先从右手开始拿筷子。
  {
   if(Tman[i] == 0)   //i-1为第i个哲学家的左边的筷子0表示该筷子可用,1表示正在被用
   {
    Tman[i] = 1;
    if(Tman[i - 1] == 0)
    {
     Tman[i - 1] = 1;
     return 1;
    }
    else
    {
     Tman[i] = 0;
     return 0;
 
    }
   }
   else
   {

    return 0;
 
   }
  }
 }
 else
 {
  if(Tman[5] == 0)
  {
   Tman[5] = 1;
   if(Tman[1] == 0)
   {
     Tman[1] = 1;
     return 1;
   }
   else
   {
    Tman[5] = 0;
    return 0;
   }

  }
  else
  {
   return 0;
  }
 }

}

void eat()   //n表示要吃的第n块肉
{
 int i;

 for(i=1;i<=people;i++)
 {
  int want; //想吃肉的哲学家
  want = 1 + rand()%5;
  if(getkey(want) && n<=meat)
  {
   Eating[want] = 1;
   Thinking[want] = 0;
   printf("第%d个哲学家开始吃第%d块肉/n",want,n);
   MeatNo[want] = n;
   EatTimeAll[want] = 1 + rand() % 3;  //哲学家不会无止境的吃下去的,
   //EatTime[i] = EatTimeAll[i];       //我设以3分钟内的随机时间为
   n++;
  }
 
 }
  
}

void eatting()
{
 int i;
 for(i=1;i<=5;i++)
 {
  
  if(Eating[i] == 1)
  {
   EatTime[i]++;
   printf("第%d个哲学家正在吃第%d块肉,共需%d秒,已用%d秒/n",i,MeatNo[i],EatTimeAll[i],EatTime[i]);      
  }  
  if(EatTime[i] == EatTimeAll[i] && EatTime[i] != 0)
   {
    printf("第%d个哲学家已经吃完第%d块肉/n",i,MeatNo[i]);
    MeatNo[i] = 0;
    Tman[i-1] = 0;
    Tman[i] = 0;
    Eating[i] = 0;
    Thinking[i] = 1;
    EatTime[i] = 0;
   }
 
 }
}

void thinking()
{
 int i;
 for(i=1;i<=5;i++)
 {
  if(Thinking[i])
  {
   printf("第%d个哲学家正在思考。/n",i);
  }
 }
}


void main()
{
 int i,time;

 //初始化
 for( i=1 ; i <= people ; ++i )
    {
         Tman[i] = 0;
   EatTime[i] = 0;
   Eating[i] = 0;
   Thinking[i] = 1;
        
    }

 
 time = 0;
 for(;n<=meat;)
    {
  ++time;
  printf("=================这是第%d秒的开始==================/n",time);
  eat();
  thinking();
  //eatTime();
  eatting();
  printf("=================这是第%d秒的结束==================/n/n",time);
 }
    printf("哈哈,盘子里已经没有肉了./n");
}

[/code]

原创粉丝点击