using System;
namespace 银行家算法
{
class MainClass
{
public class Banker {
static int[] available = new int[4]; //资源数
static int[,] max = new int[5,4]; //最大资源需求
static int[,] allocation = new int[5,4]; //已经分配的资源
static int[,] need = new int[5,4]; //还需要的资源
static int[] request = new int[4]; //存放请求
int thread; //线程号
//初始化各类的值
public void getData(){
Console.Write("请输入A,B,C,D四类资源的数目:");
//输入A,B,C三类资源数量
for(int i = 0; i < 4; i++){
available [i] = int.Parse (Console.ReadLine ());
}
//输入进程对三类资源的最大需求
for(int i = 0; i < 5; i++){
Console.WriteLine("请输入进程" + i + "对A,B,C,D三类资源的最大需求");
for(int j = 0; j < 4; j++){
max [i,j] = int.Parse (Console.ReadLine ());
}
}
//输入进程分配的三类资源数
for(int i = 0; i < 5; i++){
Console.WriteLine("请输入进程" + i + "已分配的A,B,C,D三类资源数");
for(int j = 0; j < 4; j++){
allocation[i,j] = int.Parse (Console.ReadLine ());
}
}
//计算进程还需要的三类资源数
for(int i = 0; i < 5; i++){
for(int j = 0; j < 4; j++){
need[i,j] = max[i,j] - allocation[i,j];
}
}
//重新计算available
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++){
available[i] -= allocation[j,i];
}
}
}
//用户输入要申请资源的线程和申请的资源,并进行判断
public void getThread(){
Console.WriteLine("请输入申请资源的线程");
int thread = int.Parse(Console.ReadLine()); //线程
if(thread < 0 || thread > 4){
Console.WriteLine("该线程不存在,请重新输入");
getThread();
}else{
this.thread = thread;
Console.WriteLine("请输入申请的资源(0-4)");
for(int i = 0; i < 4; i++){
request[i] = int.Parse(Console.ReadLine());
}
if(request[0] > need[thread,0] || request[1] > need[thread,1] || request[2] > need[thread,2] || request[3] > need[thread,3]){
Console.WriteLine(thread+"线程申请的资源超出其需要的资源,请重新输入");
getThread();
}else{
if(request[0] > available[0] || request[1] > available[1] || request[2] > available[2] || request[3] > available[3]){
Console.WriteLine(thread + "线程申请的资源大于系统资源,请重新输入");
getThread();
}
}
changeData(thread);
if(check(thread)){
getThread();
}else{
recoverData(thread);
getThread();
}
}
}
//thread线程请求响应后,试探性分配资源
public void changeData(int thread){
for(int i = 0; i < 4; i++){
//重新调整系统资源数
available[i] -= request[i];
//计算各个线程拥有资源
allocation[thread,i] += request[i];
//重新计算需求
need[thread,i] -= request[i];
}
}
//安全性检查为通过,分配失败时调用,恢复系统原状
public void recoverData(int thread){
for(int i = 0; i < 4; i++){
//重新调整系统资源数
available[i] += request[i];
//计算各个线程拥有资源
allocation[thread,i] -= request[i];
//重新计算需求
need[thread,i] += request[i];
}
}
//对线程thread安全性检查
public bool check(int thread){
bool[] finish = new bool[5];
int[] work = new int[4];
int[] queue = new int[5]; //由于存放安全队列
int k = 0;//安全队列下标
int j; //要判断的线程
int i;
//是否分配的标志
for( i = 0; i < 5; i++)
finish[i] = false;
j = thread;
for(i = 0; i < 4; i++){
work[i] = available[i];
}
while(j < 5){
for( i = 0; i < 4; i++){
if(finish[j]){
j++;
break;
}else if(need[j,i] > work[i]){
//(need[j,i]+"*"+i+work[i]);
j++;
break;
}else if(i == 2){
for(int m = 0; m < 4; m++){
work[m] += allocation[j,m];
}
finish[j] = true;
queue[k] = j;
k++;
j = 0; //从最小线程再开始判断
}
}
}
//判断是否都属于安全状态
for(int p = 0; p < 5; p++){
if(finish[p] == false){
Console.WriteLine("系统不安全,资源申请失败");
return false;
}
}
Console.WriteLine("资源申请成功,安全队列为:");
for(int q = 0; q < 5; q++){
Console.WriteLine (queue [q]);
}
return true;
}
//输出need和available
public void showData(){
Console.WriteLine("need");
for(int i = 0; i < 5; i++){
for(int j = 0; j < 4; j++){
Console.WriteLine (need [i, j] + " ");
}
}
Console.WriteLine("available");
for(int j = 0; j < 4; j++){
Console.WriteLine(available[j] + " ");
}
}
static void Main(string[] args) {
Banker bk = new Banker();
bk.getData();
bk.getThread();
}
}
}
}