zoukankan      html  css  js  c++  java
  • 操作系统——哲学家进餐问题的解决方法

    问题描述

    五个哲学家共用一张圆桌,分别坐在五张椅子上,圆桌上有五个碗和五只筷子。平时哲学家进行思考,当即饥饿时拿起左右两边的筷子,只有拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。

    问题分析

    这是经典的进程同步问题。筷子是临界资源,每只筷子都用一个互斥量表示。
    semaphore chopstick[5] = {1, 1, 1, 1, 1}
    错误示例:

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

    这样做会带来一个问题,当五个哲学家同时饥饿拿起左边的筷子时,试图拿右边的筷子,就会进入死锁。

    解决方法

    1.至多有四位哲学家同时拿起左边的筷子,即至多只有四个哲学家同时进餐,这样能保证至少有一个哲学家能够进餐。
    2.仅当哲学家左右两边的筷子都可用时,才能进餐
    3.规定奇数号哲学家先拿左边的筷子,再拿右边的筷子;偶数号哲学家相反。

    解法1

    用一个信号量counter表示哲学家同时进餐的人数,初始值为4

    semaphore chopstick[5] = {1, 1, 1, 1, 1};
    counter=4;
    void philosopher(int i){
        do{
            wait(counter);
            wait(chopstick[i]);
            wait(chopstick[(i+1)%5]);
            //eat
            //...
            signal(chopstick[i]);
            signal(chopstick[(i+1)%5]);
            signal(counter)
            //think
            //...
        }while(true);
    }
    

    解法2

    使用AND型信号量,当两个临界资源都满足后才能进餐

    semaphore chopstick[5] = {1, 1, 1, 1, 1};
    void philosopher(int i){
        do{
            Swait(chopstick[i], chopstick[(i+1)%5]);
            //eat
            //...
            Ssignal(chopstick[i], chopstick[(i+1)%5]);
            //think
            //...
        }while(true);
    }
    

    解法3

    semaphore chopstick[5] = {1, 1, 1, 1, 1};
    void philosopher(int i){
        do{
            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]);
            //think
            //...
        }while(true);
    }
    
    作者:inss!w!
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 相关阅读:
    生成实用包装码
    区分排序函数
    mysql优化
    高并发、大流量、大存储
    数据库的搬移
    linux查看系统日志及具体服务日志
    springboot拦截器实现
    使用ajax的get请求渲染html
    百度echarts折线图使用示例
    前端特殊符号转码
  • 原文地址:https://www.cnblogs.com/Hfolsvh/p/15395344.html
Copyright © 2011-2022 走看看