模擬實現銀行家調度算法
實驗四 模擬實現銀行家調度算法
1.實驗目的
(1)使學生加深對死鎖的理解,理解預防死鎖的思想和方法,使學生明確系統安全狀態的概念。
(2)使學生能利用銀行家調度算法實現避免死鎖。
2.實驗預備內容
閱讀死鎖的基本概念,產生死鎖的原因、產生死鎖的必要條件以及處理死鎖的基本方法,重點閱讀關於死鎖避免的章節。
3.實驗環境
(1)一臺運行Windows XP操作系統的計算機。
(2)選用turbo c、visual c++、Java等任何一種語言,建議用c++和Java。
4.實驗時間:4個機時。
5.實驗內容
(1)設置銀行家算法中的數據結構
(a)可利用資源向量Available
它是一個含有m個元素的數組,其中的每一個元素代表一類可利用資源的數目,其初始值是系統中所配置該類全部可用資源數目。其數值隨該類資源的分配和回收而動態地改變。
如果Available[j]=k表示系統中現有 類資源k個。
(b)最大需求矩陣Max
這是一個 的矩陣,它定義了系統中n個進程中的每一個進程對m類資源的最大需求。
如果Max(i,j)=k,表示進程i需要 類資源的最大數目為k。
(c)分配矩陣Allocation
這是一個 的矩陣,它定義了系統中每一類資源當前已分配該每一進程的資源數。
如果Allocation(i,j)=k,表示進程i當前已分得 類資源的數目為k。
(d)分配矩陣Need
這是一個 的矩陣,用以表示每一個進程尚需的各類資源數。
如果Need(i,j)=k表示進程i還需要 類資源k個,方能完成其任務。
上述三個矩陣存在如下關系:
Need(i,j)=Max(i,j)-Allocation(i,j)
(2)銀行家算法
設 是進程 的請求向量。如果 [j]=k,表示進程 需要k個 類的資源。當 發出資源請求後,系統按下述步驟進行檢查:
① 如果 ,則轉向步驟②;否則,認為出錯,因為它所需要的資源數已超過它所宣布的最大值。
② 如果 ,則轉向步驟③;否則,表示系統中尚無足夠的的資源, 必須等待。
③系統試探把要求的資源分配給進程 ,並修改下面數據結構中的數值:
Available Available- ;
;
;
④系統執行安全性算法,檢查此次資源分配後,系統是否處於安全狀態。若安全,才正式將資源分配給進程 ,以完成本次分配;否則,將試探分配作廢,恢復原來的資源分配狀態,讓進程 等待。
(3)安全性算法
系統所執行的安全性算法描述如下:
①設置兩個向量
(a)工作向量Work。它表示系統可提供給進程繼續運行所需要的各類資源數目,它含有m個元素,執行安全算法開始時,Work:=Available。
(b)Finish。它表示系統是否有足夠的資源分配給進程,使之運行完成,開始時先做Finish[i] :=false;當有足夠資源分配給進程時,令 Finish[i] :=true。
②從進程集合中找到一個能滿足下列條件的進程:
(a) Finish[i]:=false
(b)
如找到,執行步驟③;否則執行步驟④。
③當進程 獲得資源後,可順利執行,直至完成,並釋放出分配給它的資源,故應執行:
Work:=Work+Allocationi;
Finish[i]:=true;
go to step (2)
④如果所有進程的Finish[i]:=true,則表示系統處於安全狀態;否則,系統處於不安全狀態。
6.參考算法
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
#include "windows.h"
#define MAX_PROCESS
32
//最大進程數
#define MAX_COURCE 64
//最大資源類別
int
MAX_FACT_PROCESS;
//實際總進程數
int
MAX_FACT_COURCE;
//實際資源類別數
int
Available[MAX_COURCE];
//可利用資源向量
int
Max[MAX_PROCESS][MAX_COURCE];
//最大需求矩陣
int Allocation[MAX_PROCESS][MAX_COURCE]; //分配矩陣
int
Need[MAX_PROCESS][MAX_COURCE];
//需求矩陣
int
Request_PROCESS;
//發出請求的進程
int
Request_COURCE;
//被請求資源類別
int
Request_COURCE_NEMBER;
//請求資源數
struct
COMP{
int value;
int num;
int next;
};
int flag=0;
void
Read_Initiate(void){
//讀入初始化文檔
ifstream infile("Initiate.txt");
if(!infile){
cout<<"不能打開輸入文件:"<<"Initiate.txt"<<‘\n‘;
exit(1);
}
cout<<"開始讀入初始化文檔"<<‘\n‘;
int ch;
int Array[MAX_PROCESS*MAX_COURCE*2];
int num=0;
while(infile>>ch)
Array[num++]=ch;
num=0;
MAX_FACT_COURCE=Array[num++];
for(int j=0;j<MAX_FACT_COURCE;j++)
Available[j]=Array[num++];
MAX_FACT_PROCESS=Array[num++];
for(int i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
Max[i][j]=Array[num++];
}
infile.close();
}
void
Write_Initiate(void){
//寫入初始化文檔(分配資源
ofstream outfile("Initiate.txt");
if(!outfile){
cout<<"不能打開初始化文檔:"<<‘\n‘;
exit(1);
}
int Array[MAX_PROCESS*MAX_COURCE*2];
int num=0;
Array[num++]=MAX_FACT_COURCE;
for(int i=0;i<MAX_FACT_COURCE;i++)
Array[num++]=Available[i];
Array[num++]=MAX_FACT_PROCESS;
for(i=0;i<MAX_FACT_PROCESS;i++)
for(int j=0;j<MAX_FACT_COURCE;j++)
Array[num++]=Max[i][j];
num=0;
outfile<<Array[num++]<<" ";
for(i=0;i<MAX_FACT_COURCE;i++)
outfile<<Array[num++]<<" ";
outfile<<‘\n‘<<Array[num++]<<endl;
for(i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
outfile<<Array[num++]<<" ";
outfile<<endl;
}
DWORD m_delay=3000;
Sleep(m_delay);
outfile.close();
cout<<"修改初始化文檔成功!"<<endl;
}
void
Allocated_list(void){
//讀入已分配資源列表
ifstream infile("Allocated_list.txt");
if(!infile){
cout<<"不能打開輸入文件:"<<"Allocated_list.txt"<<‘\n‘;
exit(1);
}
cout<<"開始讀入已分配資源列表"<<‘\n‘;
int ch,num=0;
int Array[MAX_PROCESS*MAX_COURCE];
while(infile>>ch)
Array[num++]=ch;
num=0;
for(int i=0;i<MAX_FACT_PROCESS;i++)
for(int j=0;j<MAX_FACT_COURCE;j++)
Allocation[i][j]=Array[num++];
infile.close();
}
void
Set_Need(void){
//設置需求矩陣
cout<<"設置需求矩陣"<<‘\n‘;
for(int i=0;i<MAX_FACT_PROCESS;i++)
for(int j=0;j<MAX_FACT_COURCE;j++)
Need[i][j]=Max[i][j]-Allocation[i][j];
}
void
Read_Request(void){
//讀入請求向量
ifstream infile("Request_list.txt");
if(!infile){
cout<<"不能打開輸入文件:"<<"Request_list.txt"<<‘\n‘;
exit(1);
}
cout<<"開始讀入請求向量"<<‘\n‘;
int Array[3];
int num=0,ch;
while(infile>>ch)
Array[num++]=ch;
Request_PROCESS=Array[0];
Request_COURCE=Array[1];
Request_COURCE_NEMBER=Array[2];
infile.close();
}
void
Write_Allocation(void){
//修改資源分配列表(資源分配)
ofstream outfile("Allocated_list.txt");
if(!outfile){
cout<<"不能打開資源分配列表:"<<‘\n‘;
exit(1);
}
for(int i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
outfile<<Allocation[i][j]<<" ";
outfile<<endl;
}
DWORD m_delay=3000;
Sleep(m_delay);
cout<<"修改資源分配列表成功!"<<endl;
outfile.close();
}
void
Allocate_Source(void){
//開始分配(已通過掃描和安全性檢測)
cout<<‘\n‘<<"開始給第"<<Request_PROCESS<<"個進程分配第"<<Request_COURCE
<<"類資源"<<Request_COURCE_NEMBER<<"個"<<endl;
Write_Initiate();
Write_Allocation();
DWORD m_delay=3000;
Sleep(m_delay);
cout<<‘\n‘<<"祝賀您,資源分配已成功!"<<endl;
}
void
Test_Safty(){
//安全性檢測
cout<<‘\n‘<<"進入安全性檢測!"<<endl;
int Work[MAX_COURCE];
for(int i=0;i<MAX_FACT_COURCE;i++){
Work[i]=Available[i];
}
bool Finish[MAX_PROCESS][MAX_COURCE];
for(i=0;i<MAX_FACT_PROCESS;i++)
for(int j=0;j<MAX_FACT_COURCE;j++)
Finish[i][j]=false;
COMP Array[32];
for(i=0;i<MAX_FACT_PROCESS;i++)
{
Array[i].value=Need[i][Request_COURCE-1];
Array[i].num=i;
}
for(i=0;i<MAX_FACT_PROCESS;i++)
for(int j=i+1;j<MAX_FACT_PROCESS;j++){
if(Array[i].value>=Array[j].value){
int t;
t=Array[j].value;
Array[j].value=Array[i].value;
Array[i].value=t;
t=Array[j].num;
Array[j].num=Array[i].num;
Array[i].num=t;
}
else continue;
}
DWORD m_delay=3000;
Sleep(m_delay);
/*for(i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
cout<<Need[i][j]<<‘\t‘;
cout<<endl;
}
*/
if(Finish[Request_PROCESS-1][Request_COURCE-1]==false&&Need[Request_PROCESS-1][Request_COURCE-1]<=Work[Request_COURCE-1])
{
Work[Request_COURCE-1]=Work[Request_COURCE-1]+Allocation[Request_PROCESS-1][Request_COURCE-1];
Finish[Request_PROCESS-1][Request_COURCE-1]=true;
}
else
{
cout<<"未通過安全性測試,不與以分配"<<endl;
exit(0);
}
for(i=0;i<MAX_FACT_PROCESS;i++){
if(Array[i].num==Request_PROCESS-1)
continue;
if(Array[i].num!=Request_PROCESS-1&&Finish[Array[i].num][Request_COURCE-1]==false&&Need[Array[i].num][Request_COURCE-1]<=Work[Request_COURCE-1]){
Work[Request_COURCE-1]=Work[Request_COURCE-1]+Allocation[Array[i].num][Request_COURCE-1];
Finish[Array[i].num][Request_COURCE-1]=true;
}
}
for(i=0;i<MAX_FACT_PROCESS;i++)
{
if(Finish[i][Request_COURCE-1]==true)
continue;
else
{
cout<<"未通過安全性測試,不與以分配"<<endl;
exit(0);
}
}
cout<<‘\n‘<<"找到一個安全序列:"<<"P"<<Request_PROCESS<<"--->";
for(i=0;i<MAX_FACT_PROCESS;i++){
if(Array[i].num==Request_PROCESS)
continue;
else
cout<<"P"<<Array[i].num<<"--->";
}
cout<<‘\n‘<<"已通過安全性測試!"<<endl;
Allocate_Source();
}
void RUN(void){ //執行銀行家算法
cout<<"*************************************************"<<‘\n‘<<"點擊1執行!"
<<‘\n‘<<"點擊2退出!"
<<‘\n‘<<"*************************************************"<<endl;
cin>>flag;
if(flag==2)
exit(0);
if(flag==1)
{
cout<<"開始掃描請求信息!"<<endl;
DWORD m_delay=3000;
Sleep(m_delay);
if(Request_COURCE_NEMBER>Need[Request_PROCESS-1][Request_COURCE-1])
{
cout<<‘\n‘<<"第"<<Request_PROCESS<<"個進程請求第"<<Request_COURCE<<"類資源"<<Request_COURCE_NEMBER<<"個"<<endl;
cout<<"可是已超出該進程尚需的該類資源的最大數量,所以不予以分配!!"<<endl;
exit(0);
}
if(Request_COURCE_NEMBER>Available[Request_COURCE-1])
{
cout<<‘\n‘<<"第"<<Request_PROCESS<<"個進程請求第"<<Request_COURCE<<"類資源"<<Request_COURCE_NEMBER<<"個"<<endl;
cout<<"可是系統中尚無足夠的資源,所以進入等待隊列!!"<<endl;
exit(0);
}
else{
Available[Request_COURCE-1]=Available[Request_COURCE-1]-Request_COURCE_NEMBER;
Allocation[Request_PROCESS-1][Request_COURCE-1]=Allocation[Request_PROCESS-1][Request_COURCE-1]+Request_COURCE_NEMBER;
Need[Request_PROCESS-1][Request_COURCE-1]=Need[Request_PROCESS-1][Request_COURCE-1]-Request_COURCE_NEMBER;
cout<<"掃描通過"<<endl;
Sleep(m_delay);
Test_Safty();
}
}
else {
cout<<"輸入錯誤,請重新輸入!"<<‘\n‘;
RUN();
}
}
void
main(void){
Read_Initiate();
cout<<MAX_FACT_COURCE<<‘\t‘;
for(int i=0;i<MAX_FACT_COURCE;i++)
cout<<Available[i]<<‘\t‘;
cout<<endl<<MAX_FACT_PROCESS<<endl;
for(i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
cout<<Max[i][j]<<‘\t‘;
cout<<endl;
}
DWORD m_delay=3000;
Sleep(m_delay);
cout<<"讀入成功"<<‘\n‘;
Allocated_list();
for(i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
cout<<Allocation[i][j]<<‘\t‘;
cout<<endl;
}
Sleep(m_delay);
cout<<"讀入成功"<<‘\n‘;
Set_Need();
for(i=0;i<MAX_FACT_PROCESS;i++){
for(int j=0;j<MAX_FACT_COURCE;j++)
cout<<Need[i][j]<<‘\t‘;
cout<<endl;
}
Sleep(m_delay);
cout<<"設置成功"<<‘\n‘;
Read_Request();
cout<<‘\n‘<<"第"<<Request_PROCESS<<"個進程請求第"<<Request_COURCE<<"類資源"<<Request_COURCE_NEMBER<<"個"<<endl;
cout<<‘\n‘<<"讀入成功"<<‘\n‘;
RUN();
}
註:數組Array[I]表示第I+1個實際意義量需要創建三個txt文本。
1.Initiate.txt文本
3 3 3 2 //共有3類資源,Available[0]=3; Available[1]=3;
Available[2]=2
5 //當前系統中有個進程
7 5 3 // Max[0][0]=7
3 2 2 //Max[1][1]=3
9 0 2
2 2 2
4 3 3
2.Allocated_list.txt文本
0 1 0 //Allocation[0][1]=1
2 0 0
3 0 2
2 1 1
0 0 2
3.Request_list.txt文本
Java程序2
import java.util.*;
public class Bank {
public static void main(String[] args) {
int process;//定義進程數量
int resource=3;//定義資源種類是3
int[] available;//可利用的資源
int[][] max,allocation,need;//分別是最大的需求數、已分配的資源、需求資源
Scanner scanner=new Scanner(System.in);
System.out.print("請輸入進程數>>");
process=scanner.nextInt();
System.out.print("請輸入可利用資源向量(已定義3個資源種類)>>");
available=new int[resource];
for (int i = 0; i < resource; i++) {
available[i]=scanner.nextInt();
}
System.out.println("請輸入分配矩陣");
allocation=new int[process][resource];
for (int i = 0; i <process ; i++) {
System.out.print("請輸入進程"+(i+1)+"已分配的資源數>>");
for (int j = 0; j < resource; j++) {
allocation[i][j]=scanner.nextInt();
}
}
System.out.println("請輸入最大需求矩陣");
max=new int[process][resource];
for (int i = 0; i <process ; i++) {
System.out.print("請輸入進程"+(i+1)+"最大需求的資源數>>");
for (int j = 0; j < resource; j++) {
max[i][j]=scanner.nextInt();
}
}
need=new int[process][resource];
for (int i = 0; i < process; i++) {
for (int j = 0; j < resource; j++) {
need[i][j]=max[i][j]-allocation[i][j];
}
}
System.out.println();
/*
* 打印資源分配表
* */
System.out.println("To時刻的資源分配表");
System.out.println(" 進程 max\t\tallocation\t need\t\tavailable");
System.out.print("P0 ");
for (int i = 0; i <resource; i++) {
System.out.print(max[0][i]+" ");
}
System.out.print(" ");
for (int i = 0; i <resource; i++) {
System.out.print(allocation[0][i]+" ");
}
System.out.print(" ");
for (int i = 0; i <resource; i++) {
System.out.print(need[0][i]+" ");
}
System.out.print(" ");
for (int i = 0; i <resource; i++) {
System.out.print(available[i]+" ");
}
System.out.println();
for (int i = 1; i < process; i++) {
System.out.print("P"+i+" ");
for (int j = 0; j < resource; j++) {
System.out.print(max[i][j]+" ");
}
System.out.print(" ");
for (int j = 0; j < resource; j++) {
System.out.print(allocation[i][j]+" ");
}
System.out.print(" ");
for (int j = 0; j < resource; j++) {
System.out.print(need[i][j]+" ");
}
System.out.println();
}
/**
* 檢查安全序列
* */
int[] work=new int[3];//定義一個數組work用來存放可利用的資源數目
for (int i = 0; i < work.length; i++) {
work[i]=available[i];//初始化work
}
boolean[] finish=new boolean[process];//定義標誌finish,表示分配資源的置為true,沒有非配的置為false
for (int i = 0; i < process; i++) {
finish[i]=false;//初始化數組finish
}
int[] array=new int[process];//定義一個數組保存安全序列
int num=1;
int count1=1;
while(num<process){
for (int i = 0; i < process; i++) {
for (int j = 0; j < 3; j++) {
if(finish[i]==false){
if(need[i][0]<=work[0]&&need[i][1]<=work[1]&&need[i][2]<=work[2]){
for (int j2 = 0; j2 < resource; j2++) {
work[j2]=work[j2]+allocation[i][j2];
}
finish[i]=true;
array[count1-1]=i;
count1++;
}
}
}
}num++;
}
int count=0;
for (int i = 0; i < array.length; i++) {
if(finish[i]==true){
count++;
}
}
if(count==process){
System.out.println("存在一個安全序列:");
for (int i = 0; i < array.length; i++) {
System.out.print("P"+array[i]+" ");
}
}
else{System.out.println("系統處於不安全狀態!");}
System.out.println();
/**
* 以下是進程請求資源時的情況
* */
boolean flag=true;
while(flag){
int[] req=new int[resource];
System.out.print("請輸入您要請求資源的 編號>>");
int choose=scanner.nextInt();
System.out.print("請輸入該進程的請求向量>>");
for (int i = 0; i < resource; i++) {
req[i]=scanner.nextInt();
}
if(req[0]<=need[choose][0]&&req[1]<=need[choose][1]&&req[2]<=need[choose][2]){
if(req[0]<=available[0]&&req[1]<=available[1]&&req[2]<=available[2]){
for (int i = 0; i < resource; i++) {
available[i]=available[i]-req[i];
allocation[choose][i]=allocation[choose][i]+req[i];
need[choose][i]=need[choose][i]-req[i];
}
int[] work1=new int[3];
for (int i = 0; i < work1.length; i++) {
work1[i]=available[i];
}
boolean[] finish1=new boolean[process];
for (int i = 0; i < process; i++) {
finish1[i]=false;
}
int[] array1=new int[process];
int num1=1;
int count11=1;
while(num1<process){
for (int i = 0; i < process; i++) {
for (int j = 0; j < 3; j++) {
if(finish1[i]==false){
if(need[i][0]<=work1[0]&&need[i][1]<=work1[1]&&need[i][2]<=work1[2]){
for (int j2 = 0; j2 < resource; j2++) {
work1[j2]=work1[j2]+allocation[i][j2];
}
finish1[i]=true;
array1[count11-1]=i;
count11++;
}
}
}
}num1++;
}
int count2=0;
for (int i = 0; i < array1.length; i++) {
if(finish1[i]==true){
count2++;
}
}
if(count2==process){
System.out.println("存在一個安全序列:");
for (int i = 0; i < array1.length; i++) {
System.out.print("P"+array1[i]+" ");
}
}
else{System.out.println("系統處於不安全狀態!");flag=false;}
System.out.println();
}else{System.out.println("資源不夠清等待!");}
}//if結束
else{System.out.println("請求資源已超過所需資源!");}
}//while結束
}
}
2
1 1 //第2個進程請求第1類資源1個Request[1][0]=1
本程序假設當前時刻只有一個進程請求某一類資源n個.
若要滿足某個進程當前時刻同時請求不止一類資源,則需要為最大需求矩陣Max,分配矩陣Allocation和需求矩陣Need增加維數,當然代碼量也將大大增加,但是算法邏輯本身並無變化.
實驗報告內容:
(1)不是描述步驟
(2)不是描述流程
(3)不是寫源程序
(4)重點是:實現的是多少個進程,多少類資源,每類資源多少個?
用什麽實現的:available,max,allocation和need.實現的是哪個進程提出的資源請求,是否滿足它!
模擬實現銀行家調度算法