操作系统中的银行家算法
银行家算法是一种资源分配和避免死锁算法,它通过模拟所有资源的预定最大可能数量的分配来测试安全性,然后进行 “ s-state ” 检查来测试可能的活动,然后决定是否允许继续分配。
为什么要叫银行家算法捏?
银行家的算法之所以这样命名,是因为它在银行系统中用于检查是否可以将贷款批准给某人。 假设银行中有n个账户持有人,其总金额为S。如果某人申请贷款,则银行首先从银行拥有的总金额中减去贷款金额,如果剩余金额更大 比S表示只有贷款得到批准。 这样做是因为,如果所有帐户持有人都来提款,那么银行可以轻松做到这一点。
换句话说,银行绝不会以一种不能再满足所有客户需求的方式来分配资金。这也银行就会一直保持安全状态。
用在银行家算法中的数据结构
设 ‘ n ’ 为系统中进程的数量,‘ m ’ 为资源类型的数量。
Available :
- 它是一个大小为“m”的一维数组,表示每种类型的可用资源数量。
- Available[j] = k表示资源类型Rj有’ k '个实例
Max :
- 它是一个大小为n*m的二维数组,定义了系统中每个进程的最大需求。
- Max[i, j] = k表示进程Pi最多可以请求资源类型Rj的’ k '个实例
Allocation :
- 它是一个大小为’ n*m '的二维数组,定义当前分配给每个进程的每种类型的资源数量。
- Allocation[ i, j ] = k表示当前分配给process Pi的资源类型为Rj的’ k '个实例
Need :
- 它是一个大小为’ n*m '的二维数组,表示每个进程的剩余资源需求。
- Need [i, j] = k 表示进程Pi当前需要资源类型Rj的’ k '个实例
- Need [ i, j ] = Max [ i, j ] – Allocation [ i, j ]
Allocation[i]指定当前分配给进程P[i]的资源,Need[i]指定进程Pi可能仍请求完成其任务的其他资源。
银行家的算法由安全算法和资源请求算法组成。
安全算法
判断系统是否处于安全状态的算法如下:
1)假设“工作”和“完成”分别是长度为“ m”和“ n”的向量。
初始化:Work = Available
Finish [i] =false;for i = 1、2、3、4….n2)找到一个i
a)Finish [i] = false
b)Need [i] <=work
如果不存在这样的i,则转到步骤(4)3)Work = Work + Allocation[i]
Finish[i] = true
转到步骤(2)继续判断4)如果对所有i而言,Finish [i] = true
则系统处于安全状态
资源请求算法
让Request[i]为进程P[i]的请求数组。
Requesti [j] = k表示流程P[i]需要k个资源类型为R[j]的实例。当process Pi发出资源请求时,将采取以下操作:
1)如果Request[i] <= Need[i]
转到步骤(2);
否则,请提出错误条件,因为该过程已超出其最大额。2)如果Request[i] <= Available
转到步骤(3);
否则,P[i]必须等待,因为资源不可用。3)让系统假装已经分配了请求的资源来处理P[i],修改状态如下:
Available = Available – Request[i]
Allocation[i]= Allocation[i]+ Request[i]
Need[i] = Need[i]– Request[i]
举栗子
考虑一个具有五个进程P0到P4以及三个资源的类型A,B,C的系统。资源类型A有10个实例,B有5个实例,类型C有7个实例。如下图:
Question1. 需求矩阵的内容是什么?
Need [i, j] = Max [i, j] – Allocation [i, j]
所以是下图的结果:
Question2.系统是否处于安全状态?如果是,那么什么是安全序列?
在给定的系统上应用安全算法,步骤如下:
Question3.如果进程P1请求一个额外的A资源类型的实例和两个C资源类型的实例,会发生什么?
我们必须确定这个新系统状态是否安全。所以,我们再次对上述数据结构执行安全算法。
因此,新的系统状态是安全的,因此我们可以立即授予进程P1的请求。
样例代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
// P0, P1, P2, P3, P4 are the Process names here
int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix
{ 2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4
int max[5][3] = { { 7, 5, 3 }, // P0 // MAX Matrix
{ 3, 2, 2 }, // P1
{ 9, 0, 2 }, // P2
{ 2, 2, 2 }, // P3
{ 4, 3, 3 } }; // P4
int avail[3] = { 3, 3, 2 }; // Available Resources
int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
cout << "Following is the SAFE Sequence" << endl;
for (i = 0; i < n - 1; i++)
cout << " P" << ans[i] << " ->";
cout << " P" << ans[n - 1] <<endl;
return 0;
}
Output:
Following is the SAFE Sequence
P1 -> P3 -> P4 -> P0 -> P2