背景简介
核心思想
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。
在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
安全序列
所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。
因此可以在资源分配之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求。这也是“银行家算法”的核心思想。
安全状态
如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁(处于不安全状态未必就是发生了死锁,但发生死锁时一定是在不安全状态)。
不安全状态
如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。
当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们在分配资源之前总是要考虑到最坏的情况。
数据结构描述
可利用资源向量Available : 含有m个元素的数组,其中每个元素代表一类可用的资源数目。Available [ j ]=K,代表系统有j类资源K个。
最大需求矩阵Max :n*m矩阵,定义系统n个进程中的每个进程对m类资源的最大需求。简单来说一行代表一个进程,一列代表一个资源。Max[ i , j ]=K表示进程 i 需要 j 类资源 K 个。
分配矩阵 Allocation: n*m矩阵,定义系统中每类资源当前已分配给每个进程的资源数。Allocation[ i , j ]=K表示进程 i 已分得 j类资源数目为 K 。
需求矩阵 Need: 表示每个进程接下来最多还需要多少资源。Need[ i , j ]=K表示进程 i 还需要 j 类资源数目为 K 。
上述矩阵满足 : Need=Max-Allocation
算法描述
安全性算法
检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,就把该进程加入安全序列,并把该进程持有的资源全部回收。
不断重复上述过程,看最终是否能让所有进程都加入安全序列。
例子
安全状态
不安全状态
C++代码实现安全性算法
#include <iostream>
#include <vector>
using namespace std;
void in_vector(vector< vector<int>>& t,int n,int m)
{//输入矩阵
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
cin >> t[i][j];
}
return;
}
void get_need(vector< vector<int>>& Allocation, vector< vector<int>>& Max,
vector< vector<int>> &Need, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
Need[i][j] = Max[i][j] - Allocation[i][j];
}
}
}
bool cmp(vector<int>& a, vector<int>& b,int m)
//对m个元素的向量比较
{
int flag = 0;
for (int i = 0; i < m; i++)
{
if (a[i] > b[i])
{
flag = 1;
break;
}
}
return flag == 0;
}
void update(vector<int>& Available, vector<int>& t, int m)
{
for (int i = 0; i < m; i++)
Available[i] += t[i];
}
int main()
{
int n, m;//n个进程,m类资源
cin >> n >> m;
vector<int> Available(m, 0);
for (int i = 0; i < m; i++)
cin >> Available[i];
vector< vector<int>> Allocation(n, vector<int>(m, 0));
vector< vector<int>> Need(n, vector<int>(m, 0));
vector< vector<int>> Max(n, vector<int>(m, 0));
cout << "输入分配矩阵" << endl;
in_vector(Allocation, n, m);
cout << "输入最大需求矩阵" << endl;
in_vector(Max, n, m);
get_need(Allocation, Max, Need, n, m);
vector<int> Security_sequence;
vector<int> flag(n, 0);//标记
while (Security_sequence.size() != n)
{
bool inspect = false;
for (int i = 0; i < n; i++)
{
if (cmp(Need[i], Available,m)&&flag[i]==0)
{
flag[i] = 1;
Security_sequence.push_back(i);
update(Available, Allocation[i],m);
inspect = true;
}
}
if (!inspect)
{
cout << "无安全序列" << endl;
break;
}
}
for (int i = 0; i < n; i++)
{
cout << Security_sequence[i] << " ";
}
}