哲学家进餐问题

1.问题描述

一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭,如图所示。

哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿的时候,才试图拿起左、 右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。

饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。

2.哲学家进餐无死锁算法

2.1 仅当哲学家的左右两支筷子都可用时,1.1才允许他拿起筷子进餐。

方法 1: 利用 AND 型信号量机制实现:

  •  在一个原语中, 将一段代码同时需要的多个临界资源, 要么全部分配给它, 要么一个都不分配, 因此不会出现死锁的情形。
  • 当某些资源不够时阻塞调用进程;
  • 由于等待队列的存在,使得对资源的请求满足 FIFO 的要求, 因此不会出现饥饿的情形。
semaphore chopstick[5]={1, 1, 1, 1, 1};
void philosopher(int I){
    while(true){
        think();
        Swait(chopstick[(I+1)]%5,chopstick[I]);
        eat();
        Ssignal(chopstick[(I+1)]%5,chopstick[I]);
    }
}

方法 2: 利用信号量的保护机制实现。

通过信号量 mutex 对 eat() 之前的取左侧和右侧筷子的操作进行保护, 使之成为一个原子操作, 这样可以防止死锁的出现。

semaphore mutex = 1 ;
semaphore chopstick[5]={1, 1, 1, 1, 1};
void philosopher(int I){
    while(true){
        think();
        wait(mutex);
        wait(chopstick[(I+1)]%5);
        wait(chopstick[I]);
        signal(mutex);
        eat();
        signal(chopstick[(I+1)]%5);
        signal(chopstick[I]);
    }
}

这个代码有个问题就是同一时间只能有一个哲学家取筷子,效率比较低。但是可以防止死锁。

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

按此规定,将是 1,4 号哲学家竞争 4 号筷子,2,3 号哲学家竞争 2 号筷子。即五个哲学家都竞争偶数号筷子,获得后,再去竞争奇数号筷子,最后总会有一个哲学家能获得两支筷子而进餐。

而申请不到的哲学家进入阻塞等待队列,根据 FIFO 原则, 则先申请的哲学家会较先可以饭, 因此不会出现饿死的哲学家。

semaphore chopstick[5]={1, 1, 1, 1, 1};
void philosopher(int i){
    while(true){
        think();
        if(i%2 == 0){
            //偶数哲学家, 先右后左。
            wait (chopstick[ i + 1 ] mod 5) ;
            wait (chopstick[ i]) ;
            eat();
            signal (chopstick[ i + 1 ] mod 5) ;
            signal (chopstick[ i]) ;
        }
        else{
            //奇数哲学家, 先左后右。
            wait (chopstick[ i]) ;
            wait (chopstick[ i + 1 ] mod 5) ;
            eat();
            signal (chopstick[ i]) ;
            signal (chopstick[ i + 1 ] mod 5) ;
        }
    }
}

 

参考:

https://www.cnblogs.com/biglucky/p/4633706.html

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值