用自己理解的语言描述,如有错误,请疯狂打脸没关系,希望能够指出来。
0. 主要思想
分配资源之前,判断系统是否安全。
银行家算法是一种资源分配和避免死锁的算法,它通过模拟所有资源的分配方式来测试安全性。
借鉴自银行借贷系统的分配策略。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。
有下面的关系:
银行家 | 操作系统 |
---|---|
银行资金 | 系统资源 |
银行客户 | 要申请资源的进程 |
描述一下就是,在操作系统中,进程申请资源的数量是有限的,每个进程在第一次申请资源时要声明完成该进程所需的最大资源量,在结束进程时,进程应及时释放资源。操作系统在进程申请的资源数量不超过自己拥有的最大值时,都应尽量满足进程的需要。
1. 数据结构
假设 n为系统中的进程数, m为资源类型的数目。
(1) 可利用资源向量Available
- 它是一个大小为m的一维数组,指示每种类型的可用资源数量。
- 其中每一个元素代表一种可利用的资源数目。
- 如Available[j]=K,则表示系统中现有 Rj 类型的资源K个。
(2) 最大资源需求矩阵Max
- 它是一个大小为n * m的二维数组,用于定义系统中每个进程对资源的最大需求量。
- 如Max[i,j]=K,则表示进程 Pi 需要 Rj 类型资源的最大数目为K。
(3) 已分配矩阵Allocation
- 它是一个大小为n * m的二维数组,用于定义当前分配给每个进程的每种类型的资源数量。
- 如Allocation[i,j]=K,则表示进程 Pi 当前已分得 Rj 类资源的数目为K。
(4) 需求矩阵Need
- 它是一个大小为n * m的二维数组,指示每个进程剩余资源需求数目。
- 如Need[i,j]=K,则表示进程 Pi 还需要 Rj 类型资源K个,方能完成任务。
它们有如下关系:
- Need[i,j] = Max[i,j] - Allocation[i,j]
- Available_Ti =
- Need中,至少有一个线程的各类型资源数目小于等于Available中的各类型资源数目,系统才为安全状态。
2. 一个栗子
2.1. 计算T0 时刻Available矩阵和Need矩阵
T0 时刻系统状态表告诉我们了Max矩阵和Allocation矩阵的情况,由公式 Need[i,j] = Max[i,j] - Allocation[i,j] 可得有Need矩阵的系统状态表如下:
系统A、B、C各资源总量为(注意,这不是Available矩阵,它减去已分配资源才是):
A | B | C |
---|---|---|
17 | 5 | 20 |
结合Allocation矩阵的情况,得到T0 时刻Available_0矩阵如下:
记作Available_0 = [2, 3, 3]
与Need矩阵比较发现,P4和P5各类型资源数目都小于等于Available_0矩阵各类型资源数目,符合要求,所以系统当前为安全状态。
所以接下来,给P4或P5分配资源都可以。以P4为例,先分配给P4。
2.2. 计算T1 时刻(P4释放资源后)Available矩阵
当P4结束,释放资源后,记为T1 时刻,Available矩阵和系统状态表如下:
记作Available_1 = [4, 3, 7]
与Need矩阵比较发现,P2、P3和P5各类型资源数目都小于等于Available_1矩阵各类型资源数目,符合要求,所以接下来,给P2、P3或P5分配资源都可以。以P5为例,先分配给P5。
2.3. 计算T2 时刻(P5释放资源后)Available矩阵
这里说明一下,随着系统的运行,Max矩阵、Allocation矩阵和Need矩阵,与未运行的线程有关的部分不变化,每次变化的只有Available矩阵,所以只需求Available矩阵即可。
当P5结束,释放资源后,记为T2 时刻,Available矩阵如下:
记作Available_2 = [7, 4, 11]
与Need矩阵比较发现,P1、P2、P3都符合要求,所以接下来,给P1、P2、P3分配资源都可以。以P3为例。
2.4. 计算其他时刻Available矩阵
依照上述方法,继续计算可得:
Available_3 (P3释放资源后)= [11, 4, 16],P1和P2都符合要求,以P2为例。
这里已不必继续计算,可得安全序列P4—>P5—>P3—>P2—>P1。
2.5. 题目答案
(1) T0 时刻为安全状态,其中一个安全序列为P4—>P5—>P3—>P2—>P1(不唯一)。
(2) T0 时刻若进程P2请求资源(0,3,4),不能实施资源分配,因为此时的Available = [2, 3, 3],C类型资源不足。
(3) 因为(2)不能实施资源分配,所以此时的Available = [2, 3, 3],若进程P4请求资源(2,0,1),能够实施资源分配。
(4) 因为(3)实施了资源分配,所以此时的Available = [0, 3, 2],若进程P1请求资源(0,2,0),能够实施资源分配。
3. 一段程序(C语言实现)
/*
Name: 银行家算法
Author: Deep Baldha (CandyZack)
Mender: Vistar Terry (万俟淋曦)
Time: 2019/10/8 16:43
*/
#include <stdio.h>
int main()
{
// P1, P2, P3, P4, P5 为线程名
int n, m, i, j, k;
n = 5; // 线程数目
m = 3; // 资源数目
// MAX 矩阵
int max[5][3] = { { 5, 5, 9 }, // P1
{ 5, 3, 6 }, // P2
{ 4, 0, 11 }, // P3
{ 4, 2, 5 }, // P4
{ 4, 2, 4 } }; // P5
// Allocation 矩阵
int alloc[5][3] = { { 2, 1, 2 }, // P1
{ 4, 0, 2 }, // P2
{ 4, 0, 5 }, // P3
{ 2, 0, 4 }, // P4
{ 3, 1, 4 } }; // P5
// Available 矩阵
int avail[3] = { 2, 3, 3 };
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;
}
}
}
}
printf("安全序列如下:\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]+1);
printf(" P%d", ans[n - 1]+1);
return (0);
}