模拟银行家算法,模拟实现动态资源分配以及随机分配算法

银行家算法是操作系统中一种最有代表性的用来避免死锁的算法。该算法在资源分配前进行安全性检测,保证系统处于安全状态,从而避免死锁。

此次课程设计的主要内容是实现算法模拟银行家算法,模拟实现动态资源分配,编写和调试一个系统动态资源的简单模拟银行家算法程序程序,观察死锁产生的条件,并使用适当的算法,有效的防止和避免死锁的发生。从而,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。

把各进程需要和已占用资源的情况记录在进程控制块中。假定进程控制块PCB的格式如下:

其中,状态有:就绪、等待和完成。当进城处于等待态时,表示系统不能满足进程的当前申请。“资源需求量”表示进程在执行过程中总共要申请的资源量。“已占资源量”表示进程目前已经得到但还未归还的资源量。因此,进程在以后还需要的剩余资源量等于资源需要总量减去已占资源量。显然每个进程的资源需求总量不应超过系统拥有的资源总量。

由于银行家算法可以避免死锁,为了观察死锁现象的发生,要求采用两个算法:银行家算法和随机算法。随机算法的分配原则是:当进程申请资源时,如果系统现存资源数能够满足进程当前申请量,就把资源分配给进程;否则,让其等待。这样,随机算法可能引起死锁。

/*
 *Copyright(c)2018,烟台大学计算机学院
 *All right reserved.
 *文件名称:bank.cpp
	 *作者:李小同
	 *完成日期;2018年7月6日
	 *版本号;v1.1
	 *
	 *问题描述:如下
	 *输入描述:功能需求
	 *程序输出:所需功能的实现
	*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define os 10;
using namespace std;
void print();
#define M 3  //进程数量
#define N 10  //资源种类
int p[M];
using namespace std;
    int Id[M];  //进程号,外部标识符
	char State[M]; //状态 R就绪 W等待 E完成
	int Request[M][N];  //当前请求量 
    int Max[M][N]={{7,5,3,1,0,1,0,1,0,1},{4,3,3,0,0,1,2,1,0,0},{3,0,6,1,2,0,0,1,1,1}};
	// int Max[M][N]={(7,5,3),(3,2,2),(9,0,2),(2,2,2),(4,3,3)};  //需求总量
	int Need[M][N];   //还需要资源数量
	//int Allocation[M][N]={(0,1,0),(2,0,0),(3,0,2),(2,1,1),(0,0,2)};    //已分配量
	int Allocation[M][N]={{0,1,3},{4,1,1},{3,0,1}};
	bool Finish[M];
    int System[N];
	int sum;
	//int Available[N];
	/*for(int p=0;p<M;p++)
	{
		sum=Allocation[p][1]+Allocation[p][2]+Allocation[p][3];
		Available[p]=System[p]-sum;
	}*/
	int Available[N]={3,3,2,8,8,8,8,8,9,8};
int Safe()
{
   int Work[N],temp[M];//temp[]用来记录进程安全执行的顺序
   int i,j,m,k=0,count;
   for(i=0;i<M;i++)
   Finish[i]=false;
   for(j=0;j<N;j++)
    Work[j]=Available[j];//把可利用资源数赋给Work[]
   for(i=0;i<M;i++)
   {
     count=0; //记录符合条件的资源数量
    for(j=0;j<N;j++)
	{
    if(Finish[i]==false &&Need[i][j]<=Work[j])
      count++;
	}
     if(count==N)//当进程各类资源都满足Need<=Work时
	 {
    for(m=0;m<N;m++)
    {
		Work[m]=Work[m]+Allocation[i][m]; //将该进程的各类资源全部收回
	}
    Finish[i]=true;
    temp[k]=i;//记录下满足条件的进程
    k++; 
    i=-1;  //将i置为-1 进行i++ 变为0  从头开始循环
	 }
   }
   for(i=0;i<M;i++)
   if(Finish[i]==false)
   {
    printf("系统不安全!!!本次资源申请不成功!!!\n");
    return 1;
   }
   printf("\n");
   printf("经安全性检查,系统安全\n");
   printf("\n");
   printf("本次安全序列:");
    for(i=0;i<M;i++)//打印安全系统的进程调用顺序
	{
    printf("进程");
    printf("%d",temp[i]);
    if(i<M-1)
    printf("->");   //当i=M时为最后一个 不需要输出->
	}
   printf("\n");
    return 0;
}
int Safe2()
{
   int Work[N],temp[M];//temp[]用来记录进程安全执行的顺序
   int i,j,m,k=0,count;
   for(i=0;i<M;i++)
   Finish[i]=false;
   for(j=0;j<N;j++)
    Work[j]=Available[j];//把可利用资源数赋给Work[]
   for(i=0;i<M;i++)
   {
     count=0; //记录符合条件的资源数量
    for(j=0;j<N;j++)
	{
    if(Finish[i]==false &&Need[i][j]<=Work[j])
      count++;
	}
     if(count==N)//当进程各类资源都满足Need<=Work时
	 {
    for(m=0;m<N;m++)
    {
		Work[m]=Work[m]+Allocation[i][m]; //将该进程的各类资源全部收回
	}
    Finish[i]=true;
    temp[k]=i;//记录下满足条件的进程
    k++; 
    i=-1;  //将i置为-1 进行i++ 变为0  从头开始循环
	 }
   }
   for(i=0;i<M;i++)
   if(Finish[i]==false)
   {
    return 1;
   }
   printf("\n");
    return 0;
}
void InitPCB() 
{
	int i,j;
    for(i=0;i<N;i++)
	  System[N]=10;
	//Max[M][N]={(7,5,3),(4,3,3),(3,0,6)};
    //Allocation[M][N]={(0,1,3),(4,1,1),(3,0,1)};
	/*for(int p=0;p<N;p++)
	{
		for(i=0;i<M;i++)
		{
		sum=Allocation[i][p]+Allocation[i][p]+Allocation[i][p];
		}
		Available[p]=System[p]-sum;
	}
	*/
	for(i=0;i<M;i++)
	{
        Id[i]=i;
		State[i]='R';
		for(j=0;j<N;j++)
			Need[i][j]=Max[i][j]-Allocation[i][j];
	}
}
int bank() 
{
	int mi,i;
	Safe();
    while (1)
    {    
        cout<<"输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
		cin>>mi;
			if(mi>=M)
			{
				cout<<"输入错误"<<endl;
				return 0;
			}
		
        cout<<"请输入进程请求资源的数量\n";
        for (i=0;i<N;i++)
        cin>>Request[mi][i];
        for (i=0;i<N;i++)
        {
            if (Request[mi][i]>Need[mi][i])
            {
                cout<<"所请求资源数超过进程的需求量!\n";
				return 0;
            }
            else if (Request[mi][i]>Available[i])
            {
                cout<<"所请求资源数超过系统所有的资源数!\n";
				return 0;
            }
		}
        for (i=0;i<N;i++)
        {
            Available[i]-=Request[mi][i];
            Allocation[mi][i]+=Request[mi][i];
            Need[mi][i]-=Request[mi][i];
        }
        if (Safe()==0)
            cout<<"同意分配请求\n";
        else
        {
            cout<<"分配失败\n";
            for (i=0;i<N;i++)
            {
                Available[i]+=Request[mi][i];
                Allocation[mi][i]-=Request[mi][i];
                Need[mi][i]+=Request[mi][i];
            }
        }
        for (i=0;i<M;i++) 
            Finish[i]=0;
        char Flag;       //标志位
        cout<<"是否再次请求分配?是请按Y/y,否请按N/n";
        while (1)
        {
            cin>>Flag;
            if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n')
            break;
            else
            {
                cout<<"请按要求重新输入:\n";
                continue;
            }
        }
        if (Flag=='Y'||Flag=='y')
		{
		print();
         continue;
		}
        else
			break;
    }
	return 0;
}
int random() 
{
	int mi,i;
    while (1)
    {
        cout<<"输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
        cin>>mi;
        cout<<"输入进程所请求的各个资源的数量\n";
        for (i=0;i<N;i++)
        cin>>Request[mi][i];
        for (i=0;i<N;i++)
        {

            if (Request[mi][i]>Need[mi][i])
            {
                cout<<"所请求资源数超过进程的需求量!\n";
                return 0;
            }
            if (Request[mi][i]>Available[i])
            {
                cout<<"所请求资源数超过系统所有的资源数!\n";
                return 0;
            }
        }
        for (i=0;i<N;i++)
        {
            Available[i]-=Request[mi][i];
            Allocation[mi][i]+=Request[mi][i];
            Need[mi][i]-=Request[mi][i];
        }
        if (Safe2()==1)
        {
            cout<<"发生死锁\n";
             return 0;
        }
        for (i=0;i<M;i++) 
            Finish[i]=0;
        char Flag;       //标志位
        cout<<"是否再次请求分配?是请按Y/y,否请按N/n";
        while (1)
        {
            cin>>Flag;
            if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n')
            break;
            else
            {
                cout<<"请按要求重新输入:\n";
                continue;
            }
        }
        if (Flag=='Y'||Flag=='y')
        continue;
        else
			break;
    }
}
void print()       //输出   
{
	int i = 0,j=0;
	printf("......................................................................\n");
	printf("\n当前状态:");
	cout<<endl;
	cout<<"当前可利用资源总量:"<<endl;
	cout<<"[";
	for(i=0;i<N;i++)
		cout<<Available[i]<<" ";
	cout<<"]"<<endl<<endl;
	cout<<"进程号"<<"         "<<"还需资源数"<<"               "<<"需求总资源数"<<endl;
	for(i=0;i<M;i++)
	{
		cout<<Id[i]<<"        ";
		cout<<"[";
		for(j=0;j<N;j++)
			cout<<Need[i][j]<<" ";
		cout<<"]      ";
			
		cout<<"[";
		for(j=0;j<N;j++)
			cout<<Max[i][j]<<" ";
		cout<<"]";
		cout<<endl;
	}
	printf("......................................................................\n");
}
int main() 
{
  //  freopen("in.txt", "r", stdin);
	int n = 9999;
	printf("                         资源分配                   \n");
	while(n != 0)
	{
	    printf("       --------------------------------------------------\n");
	    printf("      |         &*****************************&          |\n");
	    printf("      |         *      1、银行家算法          *          |\n");
	    printf("      |         *      2、随机分配算法        *          |\n");
	    printf("      |         *      0、退出程序            *          |\n");
	    printf("      |         &*****************************&          |\n");
	    printf("       --------------------------------------------------\n\n");

		printf("\n");
        
		InitPCB();
		print();
		printf("\n");
		printf("请选择:");

        scanf("%d", &n);
		printf("\n");


		if(n == 1)
        {
            bank();
            print();
        }
        else if(n == 2)
        {
            random();
			print();
        }
        else if(n == 0)
        {
            printf("感谢使用!\n");
            exit(0);
        }
        else printf("选择错误,请重新选择!\n");
	}
	return 0;
}

    原文作者:银行家问题
    原文地址: https://blog.csdn.net/tingke_/article/details/80957981
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞