银行家算法中的数据结构
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]
银行家算法
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。
(2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];
系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
安全性算法
1)设置两个向量:
工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available;
工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。
2)从进程集合中找到一个能满足下述条件的进程:
Finish[i]=false;
Need[i,j]≤Work[j];若找到,执行 (3),否则,执行 (4)
3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]=Work[i]+Allocation[i,j];
Finish[i]=true;
go to step 2;
4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态
流程图
java模拟
package System.Bank;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Banker {
private static Scanner input=new Scanner(System.in);
int n,m; //n为进程数,m为资源数
int Available[]; //可利用资源向量 系统现有j类多少资源
int Work[]; //工作向量
boolean Finsh[]; //工作向量
List<Process> processes=new ArrayList<>(); //进程队列
public Banker() {
try {
init();
} catch (IOException e) {
e.printStackTrace();
}
}
private void init() throws IOException {
System.out.println("-----------初始化-------------");
System.out.print("输入系统资源种类数:");
int m= input.nextInt();
Available=new int[m];
for(int i=0;i<m;i++){
System.out.print("----输出第"+(i+1)+"类资源的可用资源数目:");
int number= input.nextInt();
Available[i]=number;
}
System.out.print("输入进程数:");
n= input.nextInt();
Finsh=new boolean[n];
for(int i=0;i<n;i++){
System.out.println("--创建p"+i+"进程");
System.out.println("-------设置p"+i+"进程的对"+m+"种资源最大需求:");
int createMax[]=new int[m];
for(int j=0;j<m;j++){
System.out.print("-----------------对第"+(j+1)+"类资源最大需求:");
int number= input.nextInt();
createMax[j]=number;
}
System.out.println("-------设置To时刻系统对p"+i+"进程的"+m+"种资源的已分配数:");
int createAllocation[]=new int[m];
for(int j=0;j<m;j++){
System.out.print("-----------------对第"+(j+1)+"类资源已分配数:");
int number= input.nextInt();
createAllocation[j]=number;
}
String name="p"+i;
Process p=new Process(name,i,createMax,createAllocation);
processes.add(p);
CalculateAvailable(p.getAllocation());
}
System.out.println("-----------------------t0时刻的资源分配----------------------");
printProcess();
System.out.println("------------------------t0时刻资源可利用情况----------");
print(Available);
System.out.println("t0时刻资源分配是否安全:"+(isSafe()?"安全":"不安全"));
}
private void CalculateAvailable(int Allocation[]){ //计算当前系统可利用资源数
for(int i=0;i<Allocation.length;i++){
Available[i]-=Allocation[i];
}
}
public void bank(Process process) throws InterruptedException { //银行家算法
int tempAvailable[]=Available; //系统可利用资源数
int Need[]=process.getNeed(); //此进程的需求数
int Allocation[]=process.getAllocation(); //此进程的可分配数
process.Request(); //进程请求资源
int Request[]=process.getRequest(); //获取请求向量
for(int j=0;j<Request.length;j++){
if (Request[j] <= Need[j]) {
if (Request[j] <= tempAvailable[j]) {
tempAvailable[j] = tempAvailable[j] - Request[j];
Allocation[j] = Allocation[j] + Request[j];
Need[j] = Need[j] - Request[j];
} else {
System.out.println("此进程等待");
}
} else {
System.out.println("出错");
return;
}
}
if(isSafe()){ //判断是否安全
Available=tempAvailable; //分配资源
process.setAllocation(Allocation);
process.setNeed(Need);
System.out.println("此次分配安全");
}else{
System.out.println("此次分配不安全 ");
return;
}
}
private boolean isSafe(){ //安全性算法
Work=Available;
Arrays.fill(Finsh,false);
boolean is=true;
boolean vis[]=new boolean[n];
List<Process> safeList=new ArrayList<>();//安全队列
List<Process> tempList=new ArrayList<>(); //临时存储队列
tempList.addAll(processes);
Arrays.fill(vis,false);
Process process=find(tempList); //找到一个符合的进程
if(process==null) { //如果没有找到,则检查finsh工作向量
if(check()) {
return true;
}else {
return false;
}
}
while (safeList.size()<=n&&process!=null) //寻找安全序列
{
for (int j = 0; j < process.getNeed().length; j++) {
Work[j] = Work[j] + process.getAllocation()[j];
}
Finsh[process.getId()] = true;
safeList.add(process);
tempList.remove(process);
process=find(tempList);
}
if(check()){ //判断工作向量finish
System.out.print("安全序列为:");
for(Process p:safeList){
System.out.print(p.getName()+"\t");
}
System.out.println();
return true;
}else{
return false;
}
}
private Process find(List<Process> processes ){ //寻找符合条件的进程
for (int i = 0; i < processes.size(); i++) {
if(Finsh[processes.get(i).getId()] == false) {
int j;
for (j = 0; j < (processes.get(i).getNeed()).length; j++) {
if ((processes.get(i).getNeed())[j] > Work[j]) {
break;
}
}
if(j== (processes.get(i).getNeed()).length)
return processes.get(i); //找到则返回此进程
}
}
return null;
}
private boolean check(){ //检查系统的finish工作向量
for(int i=0;i<n;i++){
if(Finsh[i]==false)
return false;
}
return true;
}
public void printProcess(){ //打印函数
System.out.println("\t"+"MAX"+"\tAllocationt"+"\tNeed\t");
for (Process p:processes) {
StringBuilder str=new StringBuilder();
str.append(p.getName()+"\t");
int getMax[]=p.getMax();
for(int i=0;i<getMax.length;i++){
str.append(getMax[i]+"\t");
}
str.append("\t");
int getAllocation[]=p.getAllocation();
for(int i=0;i<getAllocation.length;i++){
str.append(getAllocation[i]+"\t");
}
str.append("\t");
int getNeed[]=p.getNeed();
for(int i=0;i<getNeed.length;i++){
str.append(getNeed[i]+"\t");
}
System.out.println(str.toString());
}
}
private void print(int temp[]){ //打印函数
StringBuilder builder=new StringBuilder();
for(int i=0;i<temp.length;i++){
builder.append(temp[i]+"\t");
}
System.out.println(builder.toString());
}
public Process getProcessById(int id){ //通过进程Id获取当前系统的某一进程
for(Process p:processes){
if(p.getId()==id){
return p;
}
}
return null;
}
}
class Process{ //进程的类对象
private String name; //进程名
private int id; //进程id
private int Max[]; //进程的最大需求数
private int Allocation[]; //进程资源已分配数
private int Need[]; //进程资源需求数
private int Request[]; //进程请求向量
public Process(String name,int id,int[] max, int[] allocation) {
this.id=id;
this.name = name;
this.Max = max;
this.Allocation = allocation;
Need=new int[Max.length];
Request=new int[Max.length];
for(int i=0;i<Max.length;i++){
Need[i]=Max[i]-Allocation[i];
}
}
public Process() {
}
public void setRjMax(int j, int k){
Max[j]=k;
}
public void setRjAllocation(int j,int k){
Allocation[j]=k;
Need[j]=Max[j]-Allocation[j];
}
public int[] getMax() {
return Max;
}
public void setMax(int[] max) {
Max = max;
}
public int[] getAllocation() {
return Allocation;
}
public void setAllocation(int[] allocation) {
Allocation = allocation;
}
public int[] getNeed() {
return Need;
}
public void setNeed(int[] need) {
Need = need;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public int[] getRequest() {
return Request;
}
public void Request() { //请求向量的函数
Scanner input=new Scanner(System.in);
System.out.println("输入请求量:");
for(int i=0;i<Request.length;i++) {
System.out.print("第"+(i+1)+"类资源的请求量:");
int number=input.nextInt();
Request[i]=number;
}
}
}
public class Main {
static Scanner input=new Scanner(System.in);
public static void main(String[] args) throws Exception {
Banker banker=new Banker();
System.out.print("输入要请求资源的进程id:");
int id=input.nextInt();
Process process=banker.getProcessById(id);
if(process!=null) {
System.out.println(process.getName() + " " + process.getId());
banker.bank(process);
}else {
System.out.println("没有此进程");
}
}
}
执行结果:
-----------初始化-------------
输入系统资源种类数:3
----输出第1类资源的可用资源数目:10
----输出第2类资源的可用资源数目:5
----输出第3类资源的可用资源数目:7
输入进程数:5
--创建p0进程
-------设置p0进程的对3种资源最大需求:
-----------------对第1类资源最大需求:7
-----------------对第2类资源最大需求:5
-----------------对第3类资源最大需求:3
-------设置To时刻系统对p0进程的3种资源的已分配数:
-----------------对第1类资源已分配数:0
-----------------对第2类资源已分配数:1
-----------------对第3类资源已分配数:0
--创建p1进程
-------设置p1进程的对3种资源最大需求:
-----------------对第1类资源最大需求:3
-----------------对第2类资源最大需求:2
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p1进程的3种资源的已分配数:
-----------------对第1类资源已分配数:2
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:0
--创建p2进程
-------设置p2进程的对3种资源最大需求:
-----------------对第1类资源最大需求:9
-----------------对第2类资源最大需求:0
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p2进程的3种资源的已分配数:
-----------------对第1类资源已分配数:3
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:2
--创建p3进程
-------设置p3进程的对3种资源最大需求:
-----------------对第1类资源最大需求:2
-----------------对第2类资源最大需求:2
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p3进程的3种资源的已分配数:
-----------------对第1类资源已分配数:2
-----------------对第2类资源已分配数:1
-----------------对第3类资源已分配数:1
--创建p4进程
-------设置p4进程的对3种资源最大需求:
-----------------对第1类资源最大需求:4
-----------------对第2类资源最大需求:3
-----------------对第3类资源最大需求:3
-------设置To时刻系统对p4进程的3种资源的已分配数:
-----------------对第1类资源已分配数:0
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:2
-----------------------t0时刻的资源分配----------------------
MAX Allocationt Need
p0 7 5 3 0 1 0 7 4 3
p1 3 2 2 2 0 0 1 2 2
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
------------------------t0时刻资源可利用情况----------
3 3 2
安全序列为:p1 p3 p0 p2 p4
t0时刻资源分配是否安全:安全
输入要请求资源的进程id:1
p1 1
输入请求量:
第1类资源的请求量:1
第2类资源的请求量:0
第3类资源的请求量:2
安全序列为:p0 p1 p2 p3 p4
此次分配安全