操作系统

哲学家就餐问题

2017-04-06  本文已影响325人  大海孤了岛
问题描述
哲学家就餐问题
方案一:
#define N 5 //哲学家个数
semaphore fork[5]; //信号量初始值为1

void philosopher(int i){ //哲学家编号:0-4
    while(true){
        think();            //哲学家在思考
        P(fork[i]);         //去拿左边的叉子
        P(fork[(i+1)%N]);   //去拿右边的叉子
        eat();              //吃面条中
        V(fork[i]);         //放下左边的叉子
        V(fork[(i+1)%N]);   //放下右边的叉子
    }
}

该方案能满足大多数情况,但仍存在这么个情况,5个哲学家同时拿起左边的刀叉,那么会导致没有人可以吃面条,导致死锁。

方案二:使用一个信号量,保证只有一个人就餐
#define N 5 //哲学家个数
semaphore fork[5]; //信号量初始值为1
semaphore mutex;    //互斥信号量,初始值为1
void philosopher(int i){ //哲学家编号:0-4
    while(true){
        think();            //哲学家在思考
        P(mutex);           //进入临界区

        P(fork[i]);         //去拿左边的叉子
        P(fork[(i+1)%N]);   //去拿右边的叉子
        eat();              //吃面条中
        V(fork[i]);         //放下左边的叉子
        V(fork[(i+1)%N]);   //放下右边的叉子

        V(mutex);           //退出临界区
    }
}

该方案是正确的,不存在死锁,但效率很低。

方案三:设置哲学家拿刀叉的时候存在差异,分奇偶来确定拿刀叉的方式
#define N 5 //哲学家个数
semaphore fork[5]; //信号量初始值为1
void philosopher(int i){ //哲学家编号:0-4
    while(true){
        think();            //哲学家在思考
        if (i % 2 == 0){
            P(fork[i]);         //去拿左边的叉子
            P(fork[(i+1)%N]);   //去拿右边的叉子
        } else {
            P(fork[(i+1)%N]);   //去拿右边的叉子
            P(fork[i]);         //去拿左边的叉子
        }

        eat();              //吃面条中
        V(fork[i]);         //放下左边的叉子
        V(fork[(i+1)%N]);   //放下右边的叉子
    }
}

注意:这里只需要对P操作进行分类,对V操作不需要进行分类,因为V操作是不会阻塞的。

上一篇 下一篇

猜你喜欢

热点阅读