美文网首页操作系统
哲学家就餐问题

哲学家就餐问题

作者: 大海孤了岛 | 来源:发表于2017-04-06 18:08 被阅读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操作是不会阻塞的。

    相关文章

      网友评论

        本文标题:哲学家就餐问题

        本文链接:https://www.haomeiwen.com/subject/iskqattx.html