/philosopher_eat.c
//#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/sem.h>#include<error.h>#include<fcntl.h>#include<signal.h>#include<sys/wait.h>int roomnum;//房间数量,通过房间数量来限制同一时间进餐的哲学家数量int chopsticks[5];//五根筷子//定义P操作intwaitsem(int sem_id){struct sembuf sem_b;
sem_b.sem_num =0;
sem_b.sem_op =-1;
sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"wait failed!");return0;}return1;}//定义V操作intsignalsem(int sem_id){struct sembuf sem_b;
sem_b.sem_num =0;
sem_b.sem_op =1;
sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"signal failed!");return0;}return1;}intmain(int argc,char argv[]){
pid_t pid;
pid_t pids[5];int i =0;char ch;//用于控制算法结束//信号量的初始化
roomnum =semget(IPC_PRIVATE,1,0666|IPC_CREAT);semctl(roomnum,0,SETVAL,4);for(i=0;i<5;i++){
chopsticks[i]=semget(IPC_PRIVATE,1,0666|IPC_CREAT);semctl(chopsticks[i],0,SETVAL,1);}//创建进程for(i=0;i<5;i++){
pid =fork();if( pid<0){fprintf(stderr,"fork philosopher failed!\n");exit(-1);}if( pid==0){while(1){//哲学家在思考printf("philosopher %d is thinking. no disterb\n", i);sleep(1);//哲学家感到饿了,进房间waitsem(roomnum);printf("philosopher %d is hungry. so he entered the room\n",i);//哲学家拿起左筷子waitsem(chopsticks[i]);printf("philosopher %d pick up left chopstick\n",i);//哲学家拿起右筷子waitsem(chopsticks[(i+1)%5]);printf("philosopher %d pick up right chopstick\n",i);//拿到两根筷子的哲学家开始吃饭printf("philosopher %d begin to eat\n",i);sleep(5-i);//哲学家吃完饭printf("philosopher %d end to eat\n",i);//哲学家放下右筷子signalsem(chopsticks[(i+1)%5]);printf("philosopher %d put down right chopstick\n",i);
//哲学家放下左筷子signalsem(chopsticks[i]);printf("philosopher %d put down left chopstick\n",i);//哲学家离开房间signalsem(roomnum);printf("philosopher %d left the room\n",i);printf("philosopher %d begin to think\n",i);sleep(1);}}else{
pids[i]=pid;}}do{
ch=getchar();if(ch=='q')for(i=0;i<5;i++)kill(pids[i],SIGTERM);}while(ch!='q');}