南昌航空大学实验报告
课程名称: 操作系统 实验名称: _避免死锁(银行家算法)
班级:110462 姓名:XXX 学号: 11046208
一 实验目的
1. 加深对死锁概念的理解。
2. 能够利用银行家算法,有效避免死锁的发生,或检测死锁的存在。
二 实验内容
实验要求用高级语言编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
1. 设计进程对各类资源最大申请表示及初值确定。
2. 设定系统提供资源初始状况。
3. 设定每次某个进程对各类资源的申请表示。
4. 编制程序,依据银行家算法,决定其申请是否得到满足。
三 实验分析
1. 设计程序类Bank,在其中设计两个类:Sources资源类和Processo类用于管理资源和进程的调度,
i. Bank拥有一个系统字段和可分配资源字段allSources
ii. 拥有一个分配资源的方法:Assign(),将进程的资源请求进行处理
iii. 拥有一个检查资源分配后,是否能安全运行的checkSafeQueue方法
2. 在类Sources中主要设计的是三个字段,用于标志A,B,C类,这三类资源
3. 在类Processor中 设计有三个字段
i. 字段name属于String类,用与标记进程的名字
ii. 字段maxSources属于Sources类,用于说明程序的最大资源占用
iii. 字段allSources属于Sources类,用于说明当前程序已经分配有的内容
iv. 字段needSources属于Sources类,用于说明当前程序最多还能申请的最大资源
4. 程序最后设计了一个test()方法,用与测试程序的状态
测试函数对参数进行了初始化,并设计了从键盘输入进行检测数据的正确性,数据请看实验结果
四 实验程序设计
package com.rainplus.banker;
import java.util.Scanner;
public class Bank {
// private Sources sysSources = new Sources(10, 5, 7);
private Sources allSources = new Sources(3, 3, 2);// TODO
// 资源类假设一共三类资源;
class Sources {
private int A;
private int B;
private int C;
public Sources(int B, int A, int C) {
super();
this.B = B;
this.A = A;
this.C = C;
}
public Sources(Sources sources) {
super();
this.B = sources.getB();
this.A = sources.getA();
this.C = sources.getC();
}
public int getB() {
return B;
}
public void setB(int B) {
this.B = B;
}
public int getA() {
return A;
}
public void setA(int A) {
this.A = A;
}
public int getC() {
return C;
}
public void setC(int C) {
this.C = C;
}
}
// 进程类,包进程使用最大内存,当前已分配内存,和需要分配内存
class Processor {
private String name;
private Sources maxSources;
private Sources allSources;
private Sources needSources;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Sources getMaxSources() {
return maxSources;
}
public void setMaxSources(Sources maxSources) {
this.maxSources = maxSources;
}
public Sources getNeedSources() {
return needSources;
}
public void setNeedSources(Sources needSources) {
this.needSources = needSources;
}
public Sources getAllSources() {
return allSources;
}
public void setAllSources(Sources allSources) {
this.allSources = allSources;
}
}
// 显示当前系统和各个进程的资源使用情况
public void showdata(Processor[] processors) {
// 显示当前可用资源
System.out.print("当前系统可分配资源为:");
showSources(allSources);
System.out.println("-----------------进程状态-------------");
System.out.println("进程号 Max Allocation Need ");
System.out.println(" A B C A B C A B C");
for (int i = 0; i < processors.length; i++) {
System.out.print(processors[i].getName() + " "
+ processors[i].getMaxSources().getA() + " "
+ processors[i].getMaxSources().getB() + " "
+ processors[i].getMaxSources().getC() + " ");
System.out.print(processors[i].getAllSources().getA() + " "
+ processors[i].getAllSources().getB() + " "
+ processors[i].getAllSources().getC() + " ");
System.out.println(processors[i].getNeedSources().getA() + " "
+ processors[i].getNeedSources().getB() + " "
+ processors[i].getNeedSources().getC() + " ");
}
System.out.println("-----------------------------------");
}
// 显示资源的数据
public void showSources(Sources sources) {
System.out.println("A:" + sources.getA() + " B:" + sources.getB()
+ " C:" + sources.getC());
}
public boolean assign(Processor[] processors, int requestNum, Sources req) {
Processor pro = processors[requestNum];
if (!(req.getA() <= pro.getNeedSources().getA()
&& req.getB() <= pro.getNeedSources().getB() && req.getC() <= pro
.getNeedSources().getC())) {
System.out.println("请求的资源数超过了所需要的最大值,分配错误");
return false;
}
if (!(req.getA() <= allSources.getA()
&& req.getB() <= allSources.getB() && req.getC() <= allSources
.getC())) {
System.out.println("尚无足够资源分配,必须等待");
return false;
}
// 分配资源
allSources.setA(allSources.getA() - req.getA());
allSources.setB(allSources.getB() - req.getB());
allSources.setC(allSources.getC() - req.getC());
pro.getAllSources().setA(pro.getAllSources().getA() + req.getA());
pro.getAllSources().setB(pro.getAllSources().getB() + req.getB());
pro.getAllSources().setC(pro.getAllSources().getC() + req.getC());
pro.getNeedSources().setA(pro.getNeedSources().getA() - req.getA());
pro.getNeedSources().setB(pro.getNeedSources().getB() - req.getB());
pro.getNeedSources().setC(pro.getNeedSources().getC() - req.getC());
boolean flag = checkSafeQueue(processors, allSources);// 进行安全性检查并返回是否安全
if (flag == true) {
System.out.println("能够安全分配");
return true;
} else {
System.out.println("不能够安全分配");
return false;
}
}
public boolean checkSafeQueue(Processor[] pros, Sources all) {
Sources temp = new Sources(all);
boolean assigned[] = new boolean[5];
int i = 0;
while (i < 5) {
if (!assigned[i] && temp.getA() >= pros[i].getNeedSources().getA()
&& temp.getB() >= pros[i].getNeedSources().getB()
&& temp.getC() >= pros[i].getNeedSources().getC()) {
temp.setA(temp.getA() + pros[i].getAllSources().getA());
temp.setB(temp.getB() + pros[i].getAllSources().getB());
temp.setC(temp.getC() + pros[i].getAllSources().getC());
System.out.println("分配成功的是:" + pros[i].getName());
assigned[i] = true;
i = 0;
} else {
i++;
}
}
for (i = 0; i < 5; i++) {
if (assigned[i] == false)
return false;
}
return true;
}
public void test() {
int processNum = 5;
// 初始化进程数据
Sources[] all = new Sources[processNum];
Sources[] max = new Sources[processNum];
Sources[] need = new Sources[processNum];
int[][] allData = { { 0, 1, 0 }, { 2, 0, 0 }, { 3, 0, 2 }, { 2, 1, 1 },
{ 0, 0, 2 } };
int[][] maxData = { { 7, 5, 3 }, { 3, 2, 2 }, { 9, 0, 2 }, { 2, 2, 2 },
{ 4, 3, 3 } };
int[][] needData = { { 7, 4, 3 }, { 1, 2, 2 }, { 6, 0, 0 },
{ 0, 1, 1 }, { 4, 3, 1 } };
for (int i = 0; i < processNum; i++) {
all[i] = new Sources(allData[i][0], allData[i][1], allData[i][2]);
max[i] = new Sources(maxData[i][0], maxData[i][1], maxData[i][2]);
need[i] = new Sources(needData[i][0], needData[i][1],
needData[i][2]);
}
Processor[] processors = new Processor[processNum];
for (int i = 0; i < processors.length; i++) {
processors[i] = new Processor();
processors[i].setName("P" + i);
processors[i].setMaxSources(max[i]);
processors[i].setAllSources(all[i]);
processors[i].setNeedSources(need[i]);
}
showdata(processors);
Scanner s = new Scanner(System.in);
int requestNum = 0;
int[] input = { 0, 0, 0 };
Sources requestSources = new Sources(0, 0, 0);
while (true)// 循环进行分配
{
System.out.println("请输入要请求的进程号(0--4):");
requestNum = s.nextInt();
System.out.println("请输入请求的资源数目:");
for (int i = 0; i < 3; i++) {
input[i] = s.nextInt();
}
requestSources.setA(input[0]);
requestSources.setB(input[1]);
requestSources.setC(input[2]);
assign(processors, requestNum, requestSources);
showdata(processors);
}
}
public static void main(String[] args) {
new Bank().test();
}
}
五 实验结果
1. 正确安全分配:
当前系统可分配资源为:A:3B:3 C:2
-----------------进程状态-------------
进程号 Max Allocation Need
AB C A B C A B C
P0 57 3 1 0 0 4 7 3
P1 23 2 0 2 0 2 1 2
P2 09 2 0 3 2 0 6 0
P3 22 2 1 2 1 1 0 1
P4 34 3 0 0 2 3 4 1
-----------------------------------
请输入要请求的进程号(0--4):1
请输入请求的资源数目:102
分配成功的是:P1
分配成功的是:P3
分配成功的是:P0
分配成功的是:P2
分配成功的是:P4
能够安全分配
当前系统可分配资源为:A:2B:3 C:0
-----------------进程状态-------------
进程号 Max Allocation Need
AB C A B C A B C
P0 57 3 1 0 0 4 7 3
P1 23 2 1 2 2 1 1 0
P2 09 2 0 3 2 0 6 0
P3 22 2 1 2 1 1 0 1
P4 34 3 0 0 2 3 4 1
-----------------------------------
请输入要请求的进程号(0--4):
2.不能安全运行:
当前系统可分配资源为:A:3B:3 C:2
-----------------进程状态-------------
进程号 Max Allocation Need
AB C A B C A B C
P0 57 3 1 0 0 4 7 3
P1 23 2 0 2 0 2 1 2
P2 09 2 0 3 2 0 6 0
P3 22 2 1 2 1 1 0 1
P4 34 3 0 0 2 3 4 1
-----------------------------------
请输入要请求的进程号(0--4):4
请输入请求的资源数目:3 3 1
不能够安全分配
当前系统可分配资源为:A:0B:0 C:1
-----------------进程状态-------------
进程号 Max Allocation Need
AB C A B C A B C
P0 57 3 1 0 0 4 7 3
P1 23 2 0 2 0 2 1 2
P2 09 2 0 3 2 0 6 0
P3 22 2 1 2 1 1 0 1
P4 34 3 3 3 3 0 1 0
-----------------------------------
请输入要请求的进程号(0--4):
六 实验体会
加深了对死锁概念的理解,能够利用银行家算法,有效避免死锁的发生,或检测死锁的存在。对进程之间的运行情况有了更加深层次的理解