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

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

 

算法原理:

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;
        }
    }
}

 

注:部分函数省略

posted on 2018-05-23 10:44  么么打123  阅读(545)  评论(0编辑  收藏  举报