安全状态
如果存在一个安全序列,那么系统处于安全状态。对于进程顺序<P1,P2,…,Pn>,有如下
Pi-need <= Pj-hold + All-available
则这一顺序为安全序列。可以保证所有进程按此顺序执行后,资源分配不会发生死锁。
银行家算法
·数据结构
1)可利用资源向量Available 是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。 2)最大需求矩阵
Max 这是一个n×m的矩阵
,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。 3)分配
矩阵Allocation 这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。 4)需求矩阵Need。 这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。Need[i,j]=Max[i,j]-Allocation[i,j]
5)采用一些符号
设X,Y是长度为n的数组,则X<=Y当且仅当对于所有i=1,2,3……n,X[i] <= Y[i]。
·安全性算法
1)设置两个长度为n的数组,Work=Available,Finish[i]=False。 2)从进程集合中找到一个满足下述条件的进程, Finish[i]==false; Needi<=Work; 如找到,执行3);否则,执行4) 3)设进程获得资源,可顺利执行,直至完成,从而释放资源。 Work=Work+Allocation; Finish[i]=true; 转2) 4)如所有的进程Finish= true,则表示安全;否则系统不安全。
·资源请求算法
Request-i是进程Pi的请求向量,若Request-i[j] = k,则Pi需要资源类型j的实例k个。
1)若Request-i>Need-i,出错,超过其最大请求。
2)若Request-i>Available,等待,当前无可用资源。
3)若当前资源可满足,则试探性地为其分配资源:
Available -= Request-i;
Allocation += Request-i;
Need-i -= Request-i;
然后此时判断安全性,若安全,交易成功,若不安全,状态回退,Pi必须等待。
·代码实现
#include <iostream>
using namespace std;
const int source = 3;///资源类型数
const int progress = 5;///进程数
int availabe[source];///当前系统可用资源
int mmax[progress][source];///进程所需最大资源
int allocation[progress][source];///已经给进程分配的资源
int need[progress][source];///进程还需要的资源
int safeSeq[progress];///安全序列
bool isLess(int a[], int b[], int len){///判断X<Y
bool less = true;
for(int i = 0; i < len; i++){
if(a[i] > b[i]){
less = false;
break;
}
}
return less;
}
bool isSafe(){///判断安全状态
int work[source];
bool finish[progress];
bool safe = true;
for(int i = 0; i < source; i++){
work[i] = availabe[i];
}
for(int i = 0; i < progress; i++){
finish[i] = false;
}
int finishCount = 0;
int seqIndex = 0;
while(finishCount < progress){
bool flag = false;
for(int i = 0; i < progress; i++){
if(finish[i] == false && isLess(need[i], work, source)){
finish[i] = true;
finishCount++;
for(int j = 0; j < source; j++){
work[j] += allocation[i][j];
}
safeSeq[seqIndex++] = i;
flag = true;
}
}
if(!flag){///找不到符合条件的i就退出
safe = false;
break;
}
}
if(safe == true){
cout << "safe!:";
for(int i = 0; i < progress; i++){
cout << safeSeq[i] << " ";
}
cout << endl;
}
else{
cout << "not safe!" << endl;
}
return safe;
}
void init(){
cout << "Input the instances of each source:\n";
for(int i = 0; i < source; i++){
cin >> availabe[i];
}
cout << "Input the max demands of each progress:\n";
for(int i = 0; i < progress; i++){
for(int j = 0; j < source; j++){
cin >> mmax[i][j];
}
}
cout << "Input the allocation of each progress:\n";
for(int i = 0; i < progress; i++){
for(int j = 0; j < source; j++){
cin >> allocation[i][j];
}
}
for(int i = 0; i < progress; i++){
for(int j = 0; j < source; j++){
need[i][j] = mmax[i][j] - allocation[i][j];
availabe[j] -= allocation[i][j];
}
}
}
void request(){
int pi;
int piRequest[source];
cout << "Input progress i and its request:\n";
cin >> pi;
for(int i = 0; i < source; i++){
cin >> piRequest[i];
}
if(isSafe()){
cout << "now is safe\n";
}
if(!isLess(piRequest, need[pi], source)){
cout << "Error! max demands overflow.\n";
return;
}
if(!isLess(piRequest, availabe, source)){
cout << "Wait for available source.\n";
return;
}
for(int i = 0; i < source; i++){///试探修改
availabe[i] -= piRequest[i];
allocation[pi][i] += piRequest[i];
need[pi][i] -= piRequest[i];
}
if(isSafe()){
cout << "Deal!\n";
}
else{///状态回退
for(int i = 0; i < source; i++){
availabe[i] += piRequest[i];
allocation[pi][i] -= piRequest[i];
need[pi][i] += piRequest[i];
}
}
}
int main(){
init();
while(true){
request();
}
return 0;
}
以上代码在code blocks17.02通过调试
测试用例
初始化:
10 5 7
7 5 3 3 2 2 9 0 2 2 2 2 4 3 3
0 1 0 2 0 0 3 0 2 2 1 1 0 0 2
Request1=(1,0,2) —–》满足;
Request4=(3,3,0)——-》没这么多资源可用
Request0=(0,2,0)———-》资源够用但会导致不安全状态