• 避免死锁问题---银行家算法


    算法背景:为实现银行家算法,在每一个新进程进入系统时,它必须申明在运行过程中,可能需要的资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当进程请求一组资源时,系统必须先确定是否拥有足够的资源分配给该进程。如果有,再进一步将这些资源分配给进程后,再检查该系统是否处于不安全状态,如果不会,再将资源真正分配给它,否则,就让进程等待。

    算法原理:

    1.银行家算法中的数据结构

      1.1 可利用资源向量Avaliable。这是一个含有m个元素的数组,其中每一个元素代表一类可利用的资源数目,其初始值为系统中所拥有的该类资源的数目,其数值随着该资源分配和回收的行为而动态的改变。如果Avaliable[j]=K,则表示系统中现在空闲的资源 j 的数目为K

      1.2 最大需求矩阵Max。这是一个n x m的矩阵,它定义了系统中每一个进程对资源m的最大需求,如果Max[i][j]=K,则表示进程 i 对资源 j 的最大需求为K

      1.3 分配矩阵 Allocation。 这是一个n x m的矩阵,它定义了系统中每一类资源当前已经分配给每一个进程的资源数。如果Allocation[i][j]=K,则表示进程 i 当前已分得 j 类资源的数目为K。

      1.4 需求矩阵Need。 这也是一个n x m的矩阵, Need[i][j]=K 表示进程 i 仍需要K个系统资源 j 才能完成任务

            Need[i][j] = Max[i][j] - Allocation[i][j]

    2.银行家算法

    设Require[i] 是进程 i 的请求向量,如果Require [i] [j] =K,则表示进程 i 需要资源 j 的数目为K,可以直接将Require设置为Need

    2.1 如果Reqiure[i][j] <= Need[i][j],便转向步骤2.2,否则则出错,需求值大于宣布的最大值

    2.2 如果Require[i][j] <= Avaliable[i][j],便转向2.3,否则表示系统资源不够,让该进程一直等待

    2.3 系统 试探性 的将资源分配给进程 i ,并修改下面数据结构中的数值:

      Avaliable[j] -=  Require[i][j]

      Allocation[i][j] += Require[i][j]

      Need[i][j] -= Require[i][j]

    2.4 系统执行安全家算法,检查该资源分配以后系统是否处于安全状态,若不安全,则撤回2.3 中的变动,继续查看后续的进程

    3.安全性算法

    3.1 设置两个向量:

        工作向量Work[m],表示系统当前可以提供给进程的m类资源的数目,其初始值与Avaliable数组的值相同

        Finish[n]:表示是否足够的进程分配给进程 i ,初始值为false,如果有则Finish[i]的值为true

    3.2 从进程集合中找到一个能满足下列条件的进程

      1 Finish[i] = false

      2 Need[i][j] <= Work[j]

      如果存在该进程,则执行3.3,否则执行3.4

    3.3 当进程 i 获得资源后,代表其能顺利执行完毕,我们只需释放它原有的分配的资源回系统即可

      Work[j] += Allocation[i][j]

      Finish[i] = true

      继续执行 3.2

    3.4 如果所有进程都满足Finish[i] = true ,则表示系统处于安全状态,否则系统处于不安全状态

    初始情况

    资源情况             Max         Allocation           Need          Avaliable

    进程               A     B      C       A     B     C        A     B     C        A     B     C

    p0              7       5      3       0     1     0         7     4     3       3      2     2

    p1              3       2      2       2     0     0         1     2     2          

    p2              9       0      2       3     0     2         6     0     0

    p3              2       2      2       2     1     1         0     1     1

    p4                4       3      3       0      0  2         4   3     1

    很明显p1满足,则 执行中 结果

    资源情况             Max         Allocation           Need          Avaliable

    进程               A     B      C       A     B     C        A     B     C        A     B     C

    p0              7       5      3       0     1     0         7     4     3       2      0     0

    p1              3       2      2       3     2     2         0     0     0          

    p2              9       0      2       3     0     2         6     0     0

    p3              2       2      2       2     1     1         0     1     1

    p4                4       3      3       0      0  2         4   3     1

    p3 p4执行后并释放

    资源情况             Max         Allocation           Need          Avaliable

    进程               A     B      C       A     B     C        A     B     C        A     B     C

    p0              7       5      3       0     1     0         7     4     3       7      3     5

    p1              3       2      2       0     0     0         0     0     0          

    p2              9       0      2       3     0     2         6     0     0

    p3              2       2      2       0     0     0         0     0     0

    p4                4       3      3       0      0  0         0     0     0

    依次类推,知道结束

    当然,安全序列并不唯一

    p1 p3 p4 p0 p2

    p1 p3 p2 p4 p1

    银行家算法主体躯干

     1 for (i = 0; i<n; ++i)
     2     {
     3         if (judgeNeed(i))//判断所需资源是否超过所需的最大值
     4         {
     5             if (judgeAvaliable(i))//判断是否有足够的空闲资源
     6             {
     7                 for (int j = 0; j<m; ++j)
     8                 {
     9                     Avaliable[j] -= require[i][j];
    10                     Allocation[i][j] += require[i][j];
    11                     Need[i][j] -= require[i][j];
    12                 }
    13 
    14                 if (!systemSafe(i))
    15                 {
    16                     for (int j = 0; j<m; ++j)
    17                     {
    18                         Avaliable[j] += require[i][j];
    19                         Allocation[i][j] -= require[i][j];
    20                         Need[i][j] += require[i][j];
    21                     }
    22                 }
    23                 else
    24                 {
    25                     cout << "safe" << endl;
    26                     break;
    27                 }
    28 
    29                 clearRequire();//进行审核下一次的请求
    30             }
    31         }
    32 
    33     }
    34 
    35     if (i == n)
    36         cout << "无分配方案" << endl;

    安全监测算法

    bool systemSafe(int flag)
    {
        bool Finish[n] = { false };
    
        for (int i = 0; i<m; ++i)
            Work[i] = Avaliable[i];
    
        //将在试探分配过的资源回收
        for (int j = 0; j<m; ++j)
            Work[j] += Allocation[flag][j];
    
        Finish[flag] = true;//表名试探资源已经释放完毕
    
        int index = getFinishFalse(0, Finish);//查找第一个为false的进程
    
        showResult();//打印第一次试探后的结果
    
        while (1)
        {
            //如果还存在一直等待的进程
            if (index != -1)
            {
                //判断该进程所需的资源数是否小于当前拥有资源数
                if (allNeedLessWork(index, Work, Finish) && Finish[index]==false)
                {
                    for (int j = 0; j < m; ++j)
                        Work[j] += Allocation[index][j];
    
                    Finish[index] = true;
                    index = 0;
    
                    showResult();//打印此时的结果
                }
                else
                    index = getFinishFalse(index+1, Finish);//因所需资源过大而需要等待,所以必须在该进程之后查找,否则会再次查找得到该进程,进入死循环
            }
            else
            {
                if (allTrue(Finish))
                    return true;
                else
                    return false;
            }
        }
    }

    注:部分函数省略

  • 相关阅读:
    ACdream HUT新生摸底训练赛 B
    ACdream HUT新生摸底训练赛 A 娜娜梦游仙境系列——诡异的钢琴 水
    Codeforces 534D Handshakes 构造 模拟 贪心
    Codeforces 534C Polycarpus' Dice 构造
    修改优先级(类写法)
    修改优先级(单独事件写法)
    修改完成状态(类写法)
    参数'未开始'没有默认值
    定义类方法过程的时候注意变量参数和实现部分要一致,否则报错无法运行
    修改完成状态(popupmenu菜单二级菜单单击事项)单击独立事件写法
  • 原文地址:https://www.cnblogs.com/cdp1591652208/p/9075714.html
Copyright © 2020-2023  润新知