欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

哲学家进餐问题

程序员文章站 2022-07-12 20:58:37
...

哲学家进餐问题

  • 问题描述
    1、五位哲学家围坐在一张圆形桌子上,桌子上有一盘饺子。每一位哲学家要么思考,要么等待,要么吃饺子。为了吃饺子,哲学家必须拿起两只筷子,但是每个哲学家旁边只有一只筷子,也就是筷子数量和哲学家数量相等,所以每只筷子必须由两个哲学家共享。设计一个算法以允许哲学家吃饭。
    2、算法必须保证互斥(没有两位哲学家同时使用同一只筷子)
    3、同时还要避免死锁(每人拿着一只筷子不放,导致谁也吃不了)
    4、限制同时吃饭的哲学家数,下面例子中同时只允许4个哲学家同时吃饭;或者通过给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则首先拿右边的筷子来避免死锁。
  • 代码示例
/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操作
int waitsem(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!");
                return 0;
        }
        return 1;
}

//定义V操作
int signalsem(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!");
                return 0;
        }
        return 1;
}

int main(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');



}
                                          
                                                                               
  • 运行结果
    哲学家进餐问题
相关标签: Linux操作系统