编制模拟“五个哲学家”问题的程序(unix操作系统系)---4

编制模拟“五个哲学家”问题的程序

一.实验目的

学习和掌握并发进程同步的概念和方法。

二.实验要求

1、程序语法

  philosopher   [ -t  <time> ]

<time>是哲学家进餐和沉思的持续时间值,缺省值为2秒。

2、五个哲学家的编号为0~4,分别用五个进程独立模拟。

3、程序的输出要简洁,仅输出每个哲学家进餐和沉思的信息。例如,当编号为3的哲学家在进餐时,就打印:

  philosopher 3 is eating

而当他在沉思时,则打印:

   philosopher 3 is thinking

除此之外不要输出其他任何信息。

4、利用课堂已教授的知识而不使用线程或IPC机制进行同步。

5、程序应该一直运行,直到人为地终止它(如按Ctrl-C或Ctrl-\)。不允许出现僵尸进程。

三.实验代码

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include"apue.h"
enum state{eat,think};
int count=0;
int time=2;
struct person{
    int id;
    int pid;
    int sta;
}pho[5];
int pid[5];
void print(int id,int i)
{
    if(i==0)
        printf("philosopher %d is eating;\n",id);
    if(i==1)
        printf("philosopher %d is thinking;\n",id);
}
char *file[5]={"chopstick1.c","chopstick2.c","chopstick3.c","chopstick4.c","chopstick5.c"};
void chopstick(void){
    int i;
    int fd;
    for(i=0;i<5;i++)
       unlink(file[i]);
}
void EatOrThink(int id)
{
    int i,j;
    int fd;
    while(1){
      if(id%2==0){
        i=(id)%5;
        if((fd=open(file[i],O_RDONLY|O_CREAT|O_EXCL,FILE_MODE))<0)
        { 
           pho[id].sta=think;
           print(id,think);
           sleep(time);
        }
        else
        {
           j=(id+1)%5;
           if((fd=open(file[j],O_RDONLY|O_CREAT|O_EXCL,FILE_MODE))<0)
           {
               unlink(file[i]);
               pho[id].sta=think;
               print(id,think); 
               sleep(time);
           }
           else
           {
             pho[id].sta=eat;
             print(id,eat); 
             sleep(time);
             unlink(file[j]);
             unlink(file[i]);
             sleep(time);
           }
        }
      }  
      else
      {
          j=(id+1)%5;
          if((fd=open(file[j],O_RDONLY|O_CREAT|O_EXCL,FILE_MODE))<0)
          {
              pho[id].sta=think;
              print(id,think); 
              sleep(time);
          }
          else
          {
              i=(id)%5;
              if((fd=open(file[i],O_RDONLY|O_CREAT|O_EXCL,FILE_MODE))<0)
              { 
                  unlink(file[j]);
                  pho[id].sta=think;
                  print(id,think); 
                  sleep(time);
              }
              else
              {
                  pho[id].sta=eat;
                  print(id,eat); 
                  sleep(time);
                  unlink(file[i]);
                  unlink(file[j]);
                  sleep(time);
              }
          }
      }
    }
}
int main(int argc,char *argv[])
{
  if(argc==3)
      {
      time=atoi(argv[2]);
      printf("time=%d\n",time);
  }
  chopstick();
  if((pid[0]=fork())<0) 
      err_sys("wait error");
  else if(pid[0]==0)
  {
      pho[0].id=0;
      pho[0].pid=getpid();
      pho[0].sta=think;  
      EatOrThink(pho[0].id);
  }     
  if((pid[1]=fork())<0) 
      err_sys("wait error");
  else if(pid[1]==0)
  {
      pho[1].id=1;
      pho[1].pid=getpid();
      pho[1].sta=think; 
      EatOrThink(pho[1].id);
  }
  if((pid[2]=fork())<0) 
      err_sys("wait error");
  else if(pid[2]==0)
  {
      pho[2].id=2;
      pho[2].pid=getpid();
      pho[2].sta=think;
      EatOrThink(pho[2].id);
  }
  if((pid[3]=fork())<0) 
      err_sys("wait error");
  else if(pid[3]==0)
  {
      pho[3].id=3;
      pho[3].pid=getpid();
      pho[3].sta=think; 
      EatOrThink(pho[3].id);
  }
  if((pid[4]=fork())<0) 
      err_sys("wait error"); 
  else if(pid[4]==0)
  {
      pho[4].id=4;
      pho[4].pid=getpid();
      pho[4].sta=think;  
      EatOrThink(pho[4].id);
  }
  wait(NULL);
}

四.实验结果:

1.编译原文件:hilosopher.c,输入:gcc philosopher.c error2e.c -o philosopher,得到可执行程序philosopher.

     

                 

2.实验结果

执行./philosopher,直到按Ctrl-C或Ctrl-\时结束。

对于无带时间的默认其缺省的时间为2秒

 

而对于带时间的函数

例如: ./philosopher –t 5

持续时间值为5.输出:

 

实验说明

1.在main函数中,首先应当先判断arge[]中的参数,如果没有时间,则将调用缺省时间为2秒。

 2. if((pid[0]=fork())<0)

      err_sys("wait error");

  else if(pid[0]==0){

      pho[0].id=0;

      pho[0].pid=getpid();

      pho[0].sta=think; 

      EatOrThink(pho[0].id);

  }    

 分别设定各个哲学家的eating与thinking的值,再调用相应的函数进行区别,当然,在函数的编写过程当中,应当尽量避免函数中五个哲学家同时僵尸,而使程序出错。

posted @ 2012-12-05 14:12  xjx_user  阅读(619)  评论(0编辑  收藏  举报