• 进餐问题及其他信号量


    哲学家问题

      五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,没人面前有一只空盘子,每两人之间放一只叉子。每个哲学家的行为是思考,感到饥饿,然后吃通心粉。为了吃通心粉,每个哲学家必须拿到两只叉子,并且每个人只能直接从自己的左边或有百年去取叉子

    使用P、V操作解决

      每一只叉子用一个信号量表示,通过对信号量执行P操作取得叉子,执行V操作放下叉子

    设置信号量:

    semaphore  fork[n];//n=5,公用信号量,用于互斥
    fork[i]=1;//设置初值,i=1,2,,, ,5
    第i个哲学家进程
    while(1){
        thingking,,,
        P(fork[i])//拿左手的叉子
        P(fork[i+1])//拿右手的叉子
        eating;
        V(fork[i+1])//放下右手的叉子
        V(fork[i]) //放下左手的叉子
        
        这样可以确保没有两个相邻的哲学家可以同时进餐
    }

    带来的问题:

      死锁--每个人拿起而且只拿起了一只叉子,并且都不放下,僵在这

      饥饿--每个人都拿起了叉子,然后动作很协调又同时放下,反复重复这个过程(长时间得不到响应)

    原因:P、V操作本身可以很好的解决同步互斥问题,但是实际中遇到的问题并不都是同步互斥问题,并且P、V操作本身也存在着缺点:操作繁琐,同步互斥操作被分散在各个进程中,使得易读性、维护性差,复杂性高,对于一些复杂问题实现不方便,存在隐患。

    如何解决?--提出了一些高级数据结构

    信号量集--AND型信号量集

    AND型信号量集是指同时需要多种资源且每种占用一个时的信号量操作

    AND型信号量集的基本思想:在一个原语中申请整段代码需要的多个临界资源,要么全部分配给它,要么一个都不分配

    AND型信号量集P原语为Swait

    AND型信号量集V原语为Ssignal

    Swait(S1,S2, ,,, ,Sn)//P原语
    {
        while(TRUE){
            if(S1>=1&&S2>=1&& ,,, && Sn>=1){
                for(i=1,i<=n;++i){
                    Si--;
                }    
                break;
            }
            else{//某些资源不够用的处理
                调用进程进入第一个小于1信号量的等待队列,阻塞调用进程;
            }
        }
    }

    Ssignal(S1, S2, …, Sn)
    {
    for (i = 1; i <= n; ++i)
      {
        ++Si;        //释放占用的资源;
        for (在Si.queue中等待的每一个进程P){    //检查每种资源的等待队列的所有进程;  
            从等待队列Si.queue中取出进程P;
            if (判断进程P是否通过Swait中的测试)
                   //注:与signal不同,这里要进行重新判断;
            {//通过检查(资源够用)时的处理;
                  进程P进入就绪队列;
              }
            else
             {//未通过检查(资源不够用)时的处理;
              进程P进入某等待队列;
              }
       }
     }
    }

    一般信号量集

    一般信号量集是指同时需要多种资源、每种资源占用的数目不同、且可分配的资源还存在一个临界值时的信号量处理

    一般信号量集的基本思路就是在AND型信号量集的基础上进行扩充,在一次原语操作中完成所有的资源申请

    进程对信号量Si的

    测试值为 ti (表示信号量的判断条件,要求Si≥ti,即当资源数量低于ti时,便不予分配)

    占用值为di(表示资源的申请量,即Si=Si-di)

    对应的P、V原语格式为:

    Swait(S1,t1,d1;,,,;Sn,tn,dn);

    Ssignal(s1,d1,;,,,;Sn,dn);

    一般信号量可以用于各种情况的资源分配和释放,几种特殊情况:

    Swait(S,d,d)表示每次申请d个资源,当少于d个时,便不分配)

    Swait(S,1,1)表示互斥信号量

    Swait(S,1,0)可作为一个可控开关(当S≥1时,允许多个进程进入临界区;当S=0时,禁止任何进程进入临界区)

  • 相关阅读:
    JS之事件及冒泡
    DOM读取和修改内联样式
    dom查询与修改的一些常用方法
    js修改this指向的三种方法(call,bind,apply)
    JS原型概念
    JS创建对象
    JS的this(谁调用就指向谁)
    变量声明提前与函数声明提前
    JS对象创建
    正则应用之数据采集房屋网站信息
  • 原文地址:https://www.cnblogs.com/fate-/p/12668730.html
Copyright © 2020-2023  润新知