操作系統——避免死鎖的銀行家算法

1. 先附上源程序(運行程序前請將註釋的文件內容創建名爲process_info.txt的文件,並放在代碼所在目錄下)

#include<iostream>
#include<stdio.h>
using namespace std;
typedef int Status;
/*FilePath路徑下文件內容(新創建txt文件並更改FilePath路徑) 
--------------------------------------------- 
NUM(PROCESS_AND_RESOURCE)
5 3
AVAILABLE
3 3 2
MAX
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
ALLOCATION
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
--------------------------------------------- */
//--------------------------宏定義----------------------------------------- 
#define OTHER_ERROR -1 		//其他請求請求資源失敗的原因(這裏沒有用到) 
#define OVER_NEED 0			//資源需求申請超出最大需求值
#define RES_NOT_ENOUGH 1	//系統無足夠資源
#define NOT_SAFE 2			//未通過安全性算法檢測 
#define OK 3				//通過安全性算法檢測,且無其他錯誤,請求資源成功
//--------------------------函數聲明---------------------------------------- 
void ReadProcessInfo();				//讀取進程的所有信息
int SafetyJudge();					//安全性檢測算法
int NeedNGWork(int Work[],int row);	//用於比較Need[row,j]和Work[j]
Status Request_BankerALG(int Request [],int x);	//判斷能否請求成功_銀行家算法
void Display();//進程信息和當前系統資源狀態顯示
void Request();//模擬進程申請資源的過程,並檢測能否成功申請
void showMenu();//菜單顯示 
//-----------------------------全局變量--------------------------------------
char FilePath[40]="process_info.txt";	
//進程和系統資源信息文件存儲位置 
int Num_Process;	//Num_Process爲當前系統的進程數量
int Num_Resource;	//Num_Resource爲當前系統可提供的資源種類數量
bool *Finish;		//用於安全性檢測算法中進程能否順利完成 
int *Available,**MAX,**Allocation,**Need,*Work;
int Readed=0;		//用於標誌是否成功讀取文件
int *Sequence;		//用於存儲安全序列 
//---------------------------------------------------------------------------
int main()
{
	int select=0;
	while(select!=-1)
	{
		showMenu();
		cout<<"----->>請輸入要進行的操作...(退出請輸入-1)"<<endl;
		cin>>select;
		switch(select)
		{
			case 1:
			{
				int yes=0;
				if(Readed)
				{
					cout<<"--->>是否重新讀取進程和系統資源信息?(1-是/0-否)"<<endl;
					cin>>yes;
					if(yes)
					{
						ReadProcessInfo();
						Readed=1;
						cout<<"數據已更新!"<<endl;
					}
					else cout<<"已選擇繼續使用原數據..."<<endl;
				}
				else
				{
					ReadProcessInfo();
					Readed=1;
				}
				break;
			}
			case 2:
			{
				if(!Readed)
				cout<<"進程和系統資源信息尚未讀取,請執行操作1!"<<endl;
				else Display();
				break;
			}
			case 3:
			{
				if(!Readed)
				cout<<"進程和系統資源信息尚未讀取,請執行操作1!"<<endl;
				else SafetyJudge();
				break;
			}
			case 4:
			{
				if(!Readed)
				cout<<"進程和系統資源信息尚未讀取,請執行操作1!"<<endl;
				else Request();
				break;
			}
			default:break;
		}
	}
	return 0;
}
int SafetyJudge()//安全性檢測算法
{
	int i,j,k=0;
	Work=new int[Num_Resource];
	for(i=0;i<Num_Resource;i++)
	Work[i]=Available[i];	//以Available[]作爲Work[]的初值 
	int FALSE=1;
	for(i=0;i<Num_Process;i++)
		Finish[i]=false;//每調用一次安全性檢測算法SafetyJudge,初始化Finish[]爲false
	while(1)
	{
		FALSE=1;
		for(i=0;i<Num_Process;i++)
		{
			if(Finish[i]==false&&NeedNGWork(Work,i))//滿足條件1和2
			{
				FALSE=0;
				//cout<<i<<" satisfied!"<<endl;
				Sequence[k]=i;//記錄安全序列
				k++;
				for(j=0;j<Num_Resource;j++)
				{
					Work[j]=Work[j]+Allocation[i][j];
					Finish[i]=true;
				}
			}
		}
		if(FALSE==1)
			break;
	}
	for(i=0;i<Num_Process;i++)
		if(Finish[i]==false)
			break;
	if(i<Num_Process)
	{
		cout<<"該狀態未通過安全性檢測"<<endl;
		return 0;
	}
	else 
	{
		cout<<"該狀態通過安全性檢測,安全序列爲:"<<endl;
		cout<<"| ";
		for(i=0;i<Num_Process;i++)
			cout<<"P"<<Sequence[i]<<" ";
		cout<<"|"<<endl;
		return 1;
	}	//所有進程都能夠完成則返回1,否則返回0
}
int NeedNGWork(int Work[],int row)//用於比較Need[row,j]和Work[j]
{
	int *need=new int[Num_Resource];
	int i;
	for(i=0;i<Num_Resource;i++)
		need[i]=Need[row][i];
	for(i=0;i<Num_Resource;i++)
		if(need[i]>Work[i])
			break;
	if(i<Num_Resource)
		return 0;
	else return 1;//Need[row,j]<=Work[j]時,返回1,否則返回0
}
Status Request_BankerALG(int Request[],int x)
{//第x個進程提出資源請求Request[],若申請成功則返回1,否則返回-1 
	int i,j;
	
	//---------------爲初始數組分配空間-------------------------- 
	
	int *Available_init=new int[Num_Resource];
	int **Allocation_init=new int*[Num_Process];
	int **Need_init=new int *[Num_Process];
	for(i=0;i<Num_Process;i++)
	{
		Allocation_init[i]=new int[Num_Resource];
		Need_init[i]=new int[Num_Resource];
	}
	
	//------------------------------------------------------------
	for(i=0;i<Num_Resource;i++)
	Available_init[i]=Available[i];//保存Available[]原始值,在未通過安全性算法時,可將值恢復爲原始值
	for(i=0;i<Num_Process;i++)
	{
		for(j=0;j<Num_Resource;j++)
		{
			Need_init[i][j]=Need[i][j];//保存Need[][]原始值,在未通過安全性算法時,可將值恢復爲原始值
			Allocation_init[i][j]=Allocation[i][j];//保存Allocation[][]原始值,在未通過安全性算法時,可將值恢復爲原始值
		}
	}
	//-----------------------------------------------------------------------------------------------------------------
	
	for(i=0;i<Num_Resource;i++)
	if(Request[i]>Need[x][i])
	return OVER_NEED; //資源需求申請超出最大需求值
	for(i=0;i<Num_Resource;i++)
	if(Request[i]>Available[i])
	return RES_NOT_ENOUGH;	//系統無足夠資源
	for(i=0;i<Num_Resource;i++)
	{
		Available[i]-=Request[i];
		Allocation[x][i]+=Request[i];
		Need[x][i]-=Request[i];
	}
	Status Safety=SafetyJudge();
	if(Safety)
	return OK;
	else	//未通過安全性算法,恢復爲原始值
	{
		for(i=0;i<Num_Resource;i++)
		Available[i]=Available_init[i];//保存Available[]原始值,在未通過安全性算法時,可將值恢復爲原始值
		for(i=0;i<Num_Process;i++)
		{
			for(j=0;j<Num_Resource;j++)
			{
				Need[i][j]=Need_init[i][j];
				Allocation[i][j]=Allocation_init[i][j];
			}
		}
		return NOT_SAFE;
	}
}
void ReadProcessInfo()//讀取進程的所有信息 
{
	char temps[50];
	int i,j;
	FILE *fp=fopen(FilePath,"r");
	if(fp==NULL)
	{
		cout<<"文件process_info.txt讀取失敗!"<<endl;
		exit(-1);
	}
	fscanf(fp,"%s",temps);	//吸收提示字符串
	fscanf(fp,"%d%d",&Num_Process,&Num_Resource);
	fscanf(fp,"%s",temps);	//吸收提示字符串
	
	//----------------------------爲需要的所有數組分配空間------------------------------------
	
	Available=new int[Num_Resource];
	MAX=new int*[Num_Process];
	Allocation=new int*[Num_Process];
	Need=new int*[Num_Process];
	Finish=new bool[Num_Process];//爲Finsh[]數組分配空間
	Work=new int[Num_Resource];
	Sequence=new int[Num_Process];
	for(i=0;i<Num_Process;i++)
	{
		MAX[i]=new int[Num_Resource];
		Allocation[i]=new int[Num_Resource];
		Need[i]=new int[Num_Resource];
	}
	
	//----------------------------初始化所有數組-------------------------------
	
	for(i=0;i<Num_Resource;i++)
	fscanf(fp,"%d",&Available[i]);
	fscanf(fp,"%s",temps);	//吸收提示字符串
	for(i=0;i<Num_Process;i++)
	for(j=0;j<Num_Resource;j++)
	fscanf(fp,"%d",&MAX[i][j]);
	fscanf(fp,"%s",temps);	//吸收提示字符串
	for(i=0;i<Num_Process;i++)
	for(j=0;j<Num_Resource;j++)
	fscanf(fp,"%d",&Allocation[i][j]);
	
	//-----------------------------計算Need[][]--------------------------------- 
	
	for(i=0;i<Num_Process;i++)
	for(j=0;j<Num_Resource;j++)
	Need[i][j]=MAX[i][j]-Allocation[i][j];
	//--------------------以Available[]作爲Work[]的初值 ------------------------
	for(i=0;i<Num_Resource;i++)
	Work[i]=Available[i];	//以Available[]作爲Work[]的初值
	cout<<"進程和系統資源信息讀取完成!"<<endl;
	fclose(fp);
}
//TODO
void Display()//進程信息和當前系統資源狀態顯示 
{
	int i,j;
	cout<<"\t-------------------------------"<<endl; 
	cout<<"\t|當前進程數量爲"<<Num_Process<<"             |"<<endl;
	cout<<"\t|系統當前可用資源種類數量爲"<<Num_Resource<<" |"<<endl;
	cout<<"\t-------------------------------"<<endl;
	cout<<"---------------進程信息和當前系統資源狀態---------------"<<endl;
	cout<<"進程\t"<<" Max   "<<"Allocation\t"<<"Need\t"<<"Available"<<endl;
	for(i=0;i<Num_Process;i++)
	{
		cout<<"P"<<i<<"\t";
		for(j=0;j<Num_Resource;j++)
		cout<<MAX[i][j]<<" ";
		cout<<"\t";
		for(j=0;j<Num_Resource;j++)
		cout<<Allocation[i][j]<<" ";
		cout<<"\t\t";
		for(j=0;j<Num_Resource;j++)
		cout<<Need[i][j]<<" ";
		cout<<"\t";
		if(i==0)
		for(j=0;j<Num_Resource;j++)
		cout<<Available[j]<<" ";
		cout<<endl;
	}
	cout<<"--------------------------------------------------------"<<endl;
}
void Request()//模擬進程申請資源的過程,並檢測能否成功申請 
{
	int i;
	int x;//申請資源的進程編號 
	int *request=new int[Num_Resource];
	cout<<"請輸入申請資源的進程編號"<<endl;
	cin>>x;
	cout<<"--->>請輸入進程"<<x<<"申請"<<Num_Resource<<"類資源的數量"<<endl;
	for(i=0;i<Num_Resource;i++)
	cin>>request[i];
	Status result=Request_BankerALG(request,x);
	switch(result)
	{
		case OVER_NEED:cout<<"資源申請失敗(失敗原因:申請的資源量超出進程當前最大需求量!)"<<endl;break;
		case RES_NOT_ENOUGH:cout<<"資源申請失敗(失敗原因:申請的資源量超出系統當前剩餘資源量!)"<<endl;break;
		case NOT_SAFE:cout<<"資源申請失敗(失敗原因:申請後的狀態不安全,可能存在進程死鎖,無法完成資源申請!)"<<endl;break;
		case OK:cout<<"進程"<<x<<"申請資源成功!"<<endl;break;
		default:break;
	}
}
void showMenu()//菜單顯示 
{
	cout<<"\t\t|---------------------------------------------------------------|"<<endl;
	cout<<"\t\t|\t\t\t2018年6月29日\t\t                        |"<<endl;
	cout<<"\t\t|\t姓名:趙文浩	學號:16111204082                         |"<<endl;
	cout<<"\t\t|----------------------------MENU-------------------------------|"<<endl;
	cout<<"\t\t|\t1. 讀取進程和系統資源信息                               |"<<endl;
	cout<<"\t\t|\t2. 更新並顯示進程和系統資源當前狀態                     |"<<endl;
	cout<<"\t\t|\t3. 檢測當前狀態是否安全                                 |"<<endl;
	cout<<"\t\t|\t4. 進程請求資源(避免死鎖)-銀行家算法                  |"<<endl;
	cout<<"\t\t|---------------------------------------------------------------|"<<endl;
}

2. 結果截圖








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章