【面经笔记】哲学家进餐问题

哲学家进餐问题

场景:5个哲学家,5把叉子,5盘意大利面(意大利面很滑,需要两把叉子才能拿起)大家围绕桌子,进行思考与进食的活动。

哲学家的活动方式为:要么放下左右手刀叉进行思考,要么拿起刀叉开始吃饭(刀叉拿起时,必须拿两把,而且只能左右手依次拿,先左手拿左边,后右手拿右边,或者先右手拿右边,左边拿左边)。其只有这两种交替状态。

哲学家们面临的问题为:如何安排哲学家们一致的行动逻辑,保证他们至少有人且尽可能两个人能同时拿到两把叉子开始吃饭,而不会发生“死锁”,“饥饿”,“干等”的状态。需要注意的是,大家想吃饭的时机是随机的,想思考的时机也是随机的,这个不受控制,不可能由“你”来安排哲学家们哪几个先吃,哪几个后吃,他们不受你控制,但你要赋予他们一种性格,或者说思考方式,保证他们自主的思考,自主的解决问题。

  • 死锁:

大家都同时想吃饭,结果同时拿起左手边叉子,发现同时右边没有叉子,然后各怀私心,僵持者希望有人能放下他左手边叉子,然后抢夺之,开始吃意大利面,结果大家都没放。。。

  • 饥饿:

大家都同时想吃饭,结果同时拿起左手边叉子,发现同时右边没有叉子,然后都很慷慨,结果大家同时放下左手边叉子,然后大家发现有叉子了,又同时开始拿起左手边叉子,又同时放下,如此反复。。。


刀叉信号量解决方案:始终饥饿
semaphore fork[5] = { 1, 1, 1, 1, 1 };

void philosopher(int i)
{
    while (true)
    {
        think();
        wait(fork[i]);
        wait(fork[(i + 1) % 5]);
        eat();
        signal(fork[i + 1] % 5);
        signal(fork[i]);
    }
}

void main()
{
    parll_begin(
        philosopher(0),
        philosopher(1),
        philosopher(2),
        philosopher(3),
        philosopher(4),
        );
    return;
}

刀叉信号量+座位信号量解决方案:最多4个人就座,至少一个人能拿到两把。
semaphore fork[5] = { 1, 1, 1, 1, 1 };
semaphore seat = { 4 };
void philosopher(int i)
{
    while (true)
    {
        think();
        wait(seat);
        wait(fork[i]);
        wait(fork[(i + 1) % 5]);
        eat();
        signal(fork[i + 1] % 5);
        signal(fork[i]);
        signal(seat);
    }
}

void main()
{
    parll_begin(
        philosopher(0),
        philosopher(1),
        philosopher(2),
        philosopher(3),
        philosopher(4),
        );
    return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值