【操作系统】哲学家就餐问题

问题

有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。每个哲学家的行为是思考,感到饥饿,然后吃通心粉。为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
一个简单的解法是,用一个信号量表示一支筷子,这五个信号量构成信号量数组,所有信号量初始值为1,第I个哲学家的活动课描述为:

semaphore chopstick[04] = {1,1,1,1,1};
Repeat
   think;
   wait(chopstick[i]);
    wait(chopstick[(i+1) mod 5]);
    eat;
    signal(chopstick[i]);
    signal(chopstick[(i+1) mod 5]);
until false;     

若五位哲学家同时饥饿而各自拿起了左边的筷子,这使五个信号量 chopstick 均为 0,当他们试图去拿起右边的筷子时,都将因无筷子而无限期地等待下去,即可能会引起死锁。为防止死锁发生,哲学家进餐问题的改进解法:
方法一:至多只允许四位哲学家同时去拿左筷子,最终能保证至少有一位哲学家能进餐,并在用完后释放两只筷子供他人使用。
方法二:仅当哲学家的左右手筷子都拿起时才允许进餐。
方法三:规定奇数号哲学家先拿左筷子再拿右筷子,而偶数号哲学家相反。
请用PV操作描述上述三种方法。

解决方法

方法一

至多只允许四位哲学家同时去拿左筷子,最终能保证至少有一位哲学家能进餐,并在用完后释放两只筷子供他人使用

int chopstick[5] = {1, 1, 1, 1, 1};
int man = 4;  //最多4个人可以拿左筷子
Philosopher( int i ) {  //第i个哲学家
    while( true ) {
        think();
        wait( man );  //拿左筷子的哲学家不超过4个
        wait( chopstick[i] );
        wait( chopstick[ (i+1)%5 ] );
        eat();
        signal( chopstick[i] );
        signal( chopstick[(i+1)%5] );
        signal( man );
    }
}
方法二

仅当哲学家的左右手筷子都拿起时才允许进餐,否则将拿起的筷子放下

1)为便于理解(2),先使用AND型信号量

int chopstick[5] = {1, 1, 1, 1, 1};
Philosopher( int i ) {
    while( true ) {
        think();
        Swait( chopstick[i], chopstick[(i+1)%5] );
        eat();
        Ssignal( chopstick[i], chopstick[(i+1)%5] );
    }
}

(2) 使用PV操作

// 使用加锁方式,将取左右筷子的过程绑定为原子操作
int chopstick[5] = {1, 1, 1, 1, 1};
int muitex = 1;
Philosopher( int i ) {
    while( true ) {
        think();
        wait( mutex );
        wait( chopstick[i] );
        wait( chopstick[(i+1)%5] );
        signal( mutex );
        eat();
        signal( chopstick[i] );
        signal( chopstick[(i+1)%5] );
    }
}
方法三

规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则相反

int chopstick[5] = {1, 1, 1, 1, 1};
Philosopher( int i ) {
    while( true ) {
        think();

        if( i % 2 ) {  //奇数号哲学家
            wait( chopstick[i] );
            wait( chopstick[(i+1)%5] );
        } else {  //偶数号哲学家
            wait( chopstick[(i+1)%5] );
            wait( chopstick[i] );
        }

        eat();
        signal( chopstick[i] );
        signal( chopstick[(i+1)%5] );
    }
}
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值