安全状态
如果存在一个安全序列,那么系统处于安全状态。对于进程顺序<P1,P2,...,Pn>,有如下
Pi-need <= Pj-hold + All-available
则这一顺序为安全序列。可以保证所有进程按此顺序执行后,资源分配不会发生死锁。
银行家算法
·数据结构
1)可利用资源向量Available
是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。
这也是一个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]。
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)----------》资源够用但会导致不安全状态