哲学家就餐问题

OS实验-哲学家就餐问题(含代码实现)

问题描述

​五个哲学家共有五只筷子,平时,一个哲学家进行思考,饥饿时便试图取其左右最靠近它的筷子,只有他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。吃饭程序是:先取左边筷子,再取右边筷子,再吃饭,再放筷子。

实现方式

——最多只允许四个“哲学家”同时进入临界区。

​ 因为如果最多四个哲学家进入临界区,则一定有人可以吃饭,以此来解决死锁的问题。

​ 在代码实现时,以循环队列的方式为每个筷子(需要互斥访问)设一把锁(信号量,初值为1)— Chopsticks[5] = {1,1,1,1,1},若拿起筷子则置0,放下则置1,使用wait与signal函数来对数字量进行设置。同时设置一资源型信号量Room,Room最大允许值为4,最小为0。

​ 主函数中使用folk()函数来创建进程,模拟五个哲学家。

代码实现

/**
	************************************************************
	************************************************************
	*	作者: 		曾彬芮
	* 
	*	日期: 		2021-03-30
	*
	*	版本: 		V1.0
	*
	*	说明: 		哲学家就餐问题的一种解法
	************************************************************
	************************************************************
**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_BUFFER_SIZE 5
#define MAX_PHILOSOPHER 4

int Chopstick[MAX_BUFFER_SIZE] = {1,1,1,1,1};    //代表五个筷子
int Room = 0;                                    //表示有多少个哲学家在吃饭 

//函数的声明
void Wait(int number);
void Signal(int number);
void Think(int i, int my_id);
void Eat(int i, int my_id);
void Philosopher(int i, int my_id);

//函数的实现,其中wait和signal函数是用数字来模拟PV操作
void Wait(int number)
{
    number --;
}

void Signal(int number)
{
    number ++;
}

void Think(int i, int my_id)
{
    printf("I am philosopher %d and my id is: %d  I'm thinking\n",i,my_id);
}

void Eat(int i, int my_id)
{
    printf("I am philosopher %d and my id is: %d  I'm eating\n",i,my_id);
}

void Philosopher(int i, int my_id){
    if(Room==MAX_PHILOSOPHER || Chopstick[i]==0 || Chopstick[(i+1)%5] == 0){
        wait(2);
    }                           //若任何一种情况发生则等待
    Think(i,my_id);
    Signal(Room);               //Room+1,则进入临界区的哲学家人数加一
    Wait(Chopstick[i]);         //拿起左筷子
    Wait(Chopstick[(i+1)%5]);   //拿起右筷子
    Eat(i,my_id);
    Signal(Chopstick[i]);       //放下左筷子
    Signal(Chopstick[(i+1)%5]); //放下右筷子
    printf("I am philosopher %d and my id is: %d  I finished eating\n",i,my_id);
    Wait(Room);                 //哲学家离开临界区
}


int main()
{
    int i, philosopher;
    for(i=1; i<(MAX_PHILOSOPHER+1); ++i)
    {
        philosopher = fork();
        if(philosopher==-1){
            perror("fork failed");
            exit(1);
        }
        if(philosopher == 0){
            break; //防止子进程再次创建进程
        }
    }    
    sleep(1);      //等待所有进程创建完毕
    Philosopher(i, getpid());
    return 0;
}

代码完成后在Linux终端使用命令 gcc -o ### ###.c 编译,再输入 ./### 运行即可(###表示文件名)。
以上代码均为自己编写,并已在Linux虚拟机下成功编译运行,若仍有问题还劳烦各位读者朋友指正!

2021.3.31

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值