• 哲学家就餐问题


    1. 使用PV信号量使就餐互斥方案的缺点

    将就餐看成必须互斥访问的临界资源, 这样会造成资源(叉子)的浪费.五把叉子, 一次应该有两个不相邻的哲学家同时进餐.

    2. 算法实现

    数据结构

     1 #define N 5 // 哲学家个数
     2 #define LEFT i-1 // 第i个哲学家的左邻居
     3 #define RIGHT (i+1)%N // 第i个哲学家的右邻居
     4 #define THINKING 0 // 思考状态
     5 #define HUNGRY 1 // 饥饿状态
     6 #define EATING 2 // 进餐状态
     7 int state[N]; // 记录每个人的状态 0 1 2
     8 
     9 semaphore mutex = 1; // 保证操作state[N]是互斥的
    10 semaphore s[N] = 0; // 一个哲学家吃饱之后, 需要唤醒邻居, 同步

    主函数

     1 void philosopher(int i)
     2 {
     3     while (true)
     4     {
     5         think(); // 思考
     6         take_forks(i); // 尝试拿两把叉子
     7         eat(); // 进餐
     8         put_forks(i); // 放下两把叉子
     9     }
    10 }

    功能: 尝试获取两把叉子, 获取不到便阻塞

     1 // i为哲学家编号
     2 void take_forks(int i)
     3 {
     4     // 其它哲学家判断邻居时, 会读取state[N], 所以应该对state[i]进行互斥保护
     5     P(mutex);
     6     // 我饿了!
     7     state[i] = HUNGRY;
     8     // 尝试拿两把叉子
     9     test_take_left_right_forks(i);
    10     V(mutex);
    11     // 若拿到叉子, 这里就不会被阻塞, 反之同理
    12     P(s[i]);
    13 }

    功能: 放下两把叉子, 并尝试唤醒邻居

     1 void put_forks(int i)
     2 {
     3     P(mutex);
     4     // 放下两把叉子
     5     state[i] = THINKING;
     6     // 左邻居是否可以进餐
     7     test_take_left_right_forks(LEFT);
     8     // 右邻居是否可以进餐
     9     test_take_left_right_forks(RIGHT);
    10     V(mutex);
    11 }

    拿叉子策略

     1 void test_take_left_right_forks(int i)
     2 {
     3     if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
     4     {
     5         // 正在进食状态
     6         state[i] = EATING;
     7         // 通知自己进食
     8         V(s[i]);
     9     }
    10 }
  • 相关阅读:
    php过滤表单提交的html等危险代码
    浅析php过滤html字符串,防止SQL注入的方法
    PHP简单判断手机设备的方法
    如何用Math.max.apply()获取数组最大/小值
    Ubuntu14.04升级到Ubuntu16.04
    4、python数据类型之列表(list)
    3、python数据类型之字符串(str)
    centos7网卡名称修改以及配置
    rsync简单总结
    8、kvm虚拟机添加硬盘
  • 原文地址:https://www.cnblogs.com/shaohsiung/p/9977633.html
Copyright © 2020-2023  润新知