操作系统课程设计-银行家算法与随机分配算法


首先声明,以下代码参考了这位大牛。

但是这位大牛直接给出的代码,其中算法进行了优化也没有比较好的解释,这里我分析了好多时间。

程序主要就是进程模拟和算法实现,比较容易理解。



接着是对银行家算法优化的说明:(直接粘贴自己实验报告上的)

安全性算法:满足available和need的关系后,即满足安全性检查进行请求分配。满足request和need的关系以及request和available的关系后即分配资源。同时增加了就绪、等待、完成等进程状态,均在结构体中定义。
随机算法:基本与安全性算法一样,唯一的不同是安全性检查替换成available>0。

改进算法评估:

普通的安全性算法:
(1)、递交请求;
(2)、利用剩下的Available进行分配,若分配成功,则安全,输出安全序列;否则不安全,回滚,分配失败。

改进的安全性算法:

已知:一旦可以用资源比某进程需求小,那么若是实现该进程的请求,不但该进程无法执行完毕(分配了资源而无法达到目的,实质上是对资源的一种浪费,无法得到已有资源),消耗的资源很大程度上限制了其他进程的执行,从而进入不安全状态而死锁。如果在提出资源请求前就对此进程进行安全性检查,Available不满足Need即跳过该进程并等待,这样就可以避免一些无谓的请求。

优点:(1)、避免了一些无意义的请求,使请求的限制范围更加明确,现实生活中增加了效率;
(2)、相比原始银行家算法取消了资源请求后的一系列安全性检查(须用for查看是否所有资源都完成,其实也是动态分配,耗时较多),大大减少了耗时。

缺点:若请求的一部分资源过少不影响其他进程的执行,改进后的算法会屏蔽,这样其实会使一些原本有效的请求变得无法执行。

综述:银行家算法不管在现实还是避免死锁方面,目的都是查看是否可以找到一个安全序列,使所有进程(用户)满足需求。而次优化出现的缺点并不影响安全序列的结果,只是屏蔽了极少量的无意义操作,换来了算法性能提升以及时间减少,所以我认为次优化是可行的。



程序中可能有些地方还按照自己的口味改了改,不过基本思想都是那个大牛的。

ps:课程设计这种东西切记报告要写好,我报告xjb写了一通报告成绩是中等,总成绩硬是被拖到了良好= =




代码:

#include 
#include 
#include 
#define os 10

using namespace std;

struct REC
{
    int A;
    int B;
    int C;
};

struct PCB
{
	int Id;  //进程号,外部标识符
	char State; //状态 R就绪 W等待 E完成
	REC Apply;  //当前请求量
	REC Max;  //需求总量
	REC Need;   //还需要资源数量
	REC Allocation;    //已分配量
};

PCB *pos,*tmp, *pos0;

REC System, Available;

PCB pcb[3];

/*void InitPCB()
{
    printf("输入系统资源总量:\n");
    scanf("%d%d%d", &System.A, &System.B, &System.C);
	int i = 0, a = 0, b = 0, c = 0;
	for(pos = pcb; pos < pcb+3; pos++)
	{
		i++;
		pos->Id = i;
		pos->State = 'R';
		pos->Allocation.A = 0;
		pos->Allocation.B = 0;
		pos->Allocation.C = 0;
		pos->Apply.B = 0;
		pos->Apply.B = 0;
		pos->Apply.B = 0;
	}
	i = 0;
	for(pos = pcb; pos < pcb+3; pos++)
	{
	    printf("输入进程%d最大需求Max\n", ++i);
	    scanf("%d%d%d", &pos->Max.A, &pos->Max.B, &pos->Max.C);
		while(pos->Max.A>os || pos->Max.B>os || pos->Max.C>os || pos->Max.A<0 || pos->Max.B<0 || pos->Max.C<0)
		{
		    printf("数据输入有错,请重新输入:\n");
			scanf("%d%d%d", &pos->Max.A, &pos->Max.B, &pos->Max.C);
		}
		printf("输入进程%d已分配量\n", i);
	    scanf("%d%d%d", &pos->Allocation.A, &pos->Allocation.B, &pos->Allocation.C);
		while(pos->Allocation.A>pos->Max.A || pos->Allocation.B>pos->Max.B || pos->Allocation.C>pos->Max.C || pos->Allocation.A<0 || pos->Allocation.B<0 || pos->Allocation.C<0)
		{
		    printf("数据输入有错,请重新输入:\n");
			scanf("%d%d%d", &pos->Allocation.A, &pos->Allocation.B, &pos->Allocation.C);
		}
		a+=pos->Allocation.A;
		b+=pos->Allocation.B;
		c+=pos->Allocation.C;
		pos->Need.A = pos->Max.A-pos->Allocation.A;
		pos->Need.B = pos->Max.B-pos->Allocation.B;
		pos->Need.C = pos->Max.C-pos->Allocation.C;
	}
	Available.A = System.A-a;
	Available.B = System.B-b;
	Available.C = System.C-c;
}*/

void InitPCB()
{
 //   printf("输入系统资源总量:\n");
    System.A = 10;
    System.B = 5;
    System.C = 7;
	int i = 0, a = 0, b = 0, c = 0;
	for(pos = pcb; pos < pcb+3; pos++)
	{
		i++;
		pos->Id = i;
		pos->State = 'R';
		pos->Allocation.A = 0;
		pos->Allocation.B = 0;
		pos->Allocation.C = 0;
		pos->Apply.B = 0;
		pos->Apply.B = 0;
		pos->Apply.B = 0;
	}
	i = 0;
	//初始化第一个
	pos = pcb;
	pos->Max.A = 7;
	pos->Max.B = 5;
	pos->Max.C = 3;
	pos->Allocation.A = 0;
	pos->Allocation.B = 1;
	pos->Allocation.C = 3;
	a+=pos->Allocation.A;
    b+=pos->Allocation.B;
    c+=pos->Allocation.C;
    pos->Need.A = pos->Max.A-pos->Allocation.A;
    pos->Need.B = pos->Max.B-pos->Allocation.B;
    pos->Need.C = pos->Max.C-pos->Allocation.C;

    //初始化第二个
    pos = pos+1;
	pos->Max.A = 4;
	pos->Max.B = 3;
	pos->Max.C = 3;
	pos->Allocation.A = 4;
	pos->Allocation.B = 1;
	pos->Allocation.C = 1;
	a+=pos->Allocation.A;
    b+=pos->Allocation.B;
    c+=pos->Allocation.C;
    pos->Need.A = pos->Max.A-pos->Allocation.A;
    pos->Need.B = pos->Max.B-pos->Allocation.B;
    pos->Need.C = pos->Max.C-pos->Allocation.C;

    //初始化第三个
    pos = pos+1;
	pos->Max.A = 3;
	pos->Max.B = 0;
	pos->Max.C = 6;
	pos->Allocation.A = 3;
	pos->Allocation.B = 0;
	pos->Allocation.C = 1;
	a+=pos->Allocation.A;
    b+=pos->Allocation.B;
    c+=pos->Allocation.C;
    pos->Need.A = pos->Max.A-pos->Allocation.A;
    pos->Need.B = pos->Max.B-pos->Allocation.B;
    pos->Need.C = pos->Max.C-pos->Allocation.C;

    //last
	Available.A = System.A-a;
	Available.B = System.B-b;
	Available.C = System.C-c;
}


void print()
{
	int i = 0;
	printf("......................................................................\n");
	printf("\n当前状态:   {可利用量:[%d %d %d]}\n\n", Available.A, Available.B, Available.C);
	printf("进程号  状态    最近申请量     需求总量     已分配      还需求量\n");
	for(pos0 = pcb; pos0 < pcb+3; pos0++)
	{
	    printf("%d\t%c       [%d %d %d]        [%d %d %d]      [%d %d %d]     [%d %d %d]\n", pos0->Id, pos0->State, pos0->Apply.A, pos0->Apply.B, pos0->Apply.C, pos0->Max.A, pos0->Max.B, pos0->Max.C, pos0->Allocation.A, pos0->Allocation.B, pos0->Allocation.C, pos0->Need.A, pos0->Need.B, pos0->Need.C);
	}
	printf("......................................................................\n");
}

int bank()
{
    printf("\n***************************银行家算法*************************************\n\n");
	int i = 0;
	int ans[3];
	for(pos = pcb ; ; pos++)
	{
	    pos->Apply.A = pos->Apply.B = pos->Apply.C = 0;
		if(pos->State == 'R')
		{
		    //系统在进行资源分配之前,应先计算此次资源分配的安全性
		    //若此次分配不会导致系统进入不安全状态,才可将资源分配给进程
		    //安全性检查的提前减少了不必要的回滚,不安全的等待
			if(Available.ANeed.A || Available.BNeed.B || Available.CNeed.C)
			{
				pos->State = 'W';
				printf("对%d进程提出的请求会导致进入不安全状态,进程%d等待\n", pos->Id, pos->Id);
				if(pos == pcb+2) pos = pcb-1;
				continue;
			}
			//安全了再分配
            if(pos->Need.A==pos->Max.A && pos->Need.B==pos->Max.B && pos->Need.C==pos->Max.C) printf("输入第%d个进程的资源请求量\n", pos->Id);
            else printf("输入进程%d还需资源量[%d %d %d]个,将其分配给该进程:\n", pos->Id, pos->Need.A, pos->Need.B, pos->Need.C);
            scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C);
            //不满足条件一
            while(pos->Apply.A>pos->Need.A || pos->Apply.B>pos->Need.B || pos->Apply.C>pos->Need.C)
            {
                printf("资源请求量大于资源需求总量,重新输入:\n");
                scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C);
            }
            //不满足条件二,等待
            if(pos->Apply.A>Available.A || pos->Apply.B>Available.B || pos->Apply.C>Available.C)
            {
                pos->State = 'W';
                printf("可利用资源无法满足该资源请求量,进程%d等待\n", pos->Id);
                if(pos == pcb+2) pos = pcb-1;
				continue;
            }
            //第一、第二条件满足,分配
            pos->Allocation.A = pos->Allocation.A+pos->Apply.A;
            pos->Allocation.B = pos->Allocation.B+pos->Apply.B;
            pos->Allocation.C = pos->Allocation.C+pos->Apply.C;
            pos->Need.A = pos->Max.A-pos->Allocation.A;
            pos->Need.B = pos->Max.B-pos->Allocation.B;
            pos->Need.C = pos->Max.C-pos->Allocation.C;
            Available.A = Available.A-pos->Apply.A;
            Available.B = Available.B-pos->Apply.B;
            Available.C = Available.C-pos->Apply.C;
            printf("分配给进程%d[%d,%d,%d]个资源,还需[%d,%d,%d]个资源.\n", pos->Id, pos->Apply.A, pos->Apply.B, pos->Apply.C, pos->Need.A, pos->Need.B, pos->Need.C);
            print();
            //占有的等于总需求,此进程完成
            if(pos->Allocation.A==pos->Max.A && pos->Allocation.B==pos->Max.B && pos->Allocation.C==pos->Max.C)
            {
                pos->State = 'E';
                Available.A += pos->Allocation.A;
                Available.B += pos->Allocation.B;
                Available.C += pos->Allocation.C;
                pos->Allocation.A = pos->Allocation.B = pos->Allocation.C = 0;
                printf("进程[%d]已得到全部资源并释放了占有的资源!\n", pos->Id);
                print();
                ans[i] = pos->Id;
                i++;
                if(pos == pcb+2) pos = pcb-1;
            }
            //所有进程处于完成态,输出安全序列
            tmp = pcb;
            if(tmp->State=='E'&&(tmp+1)->State=='E'&&(tmp+2)->State=='E')
            {
                printf("银行家算法分配完毕,系统处于安全状态,安全序列是:%d->%d->%d\n", ans[0], ans[1], ans[2]);
                print();
                return 0;
            }
            else
            {
                if(pos == pcb+2) pos = pcb-1;
                continue;
            }
        }
		else if(pos->State == 'W')//等待状态的进程,满足就绪条件的变为就绪或直接跳过
		{
		    //如果此时可利用资源满足原本变为等待的进程资源请求,则变为就绪
            if(Available.A>pos->Apply.A && Available.A>=0 && Available.B>pos->Apply.B && Available.B>=0 && Available.C>pos->Apply.C && Available.C>=0)
            {
                pos->State = 'R';
                pos--;//变为就绪了以后须马上为其分配
            }
            else
            {
                if(pos == pcb+2) pos = pcb-1;
                continue;
            }
		}
	}
}


int random()
{
    printf("\n***************************随机按序分配算法*************************************\n\n");
	int i = 0;
	for(pos = pcb; ; pos++)
	{
        pos->Apply.A = pos->Apply.B = pos->Apply.C = 0;
		if(pos->State == 'R')
		{
		    if(Available.A<=0 || Available.B<=0 || Available.C<=0)
			{
				pos->State = 'W';
				printf("系统资源量不足暂时不能分配给进程[%d],进程等待\n", pos->Id);
                tmp = pcb;
				if(tmp->State=='W' && (tmp+1)->State=='W' && (tmp+2)->State=='W')//进程处于完成态
				{
				    printf("随机分配算法产生死锁!\n");
                    return 0;
				}
				if(pos == pcb+2) pos = pcb-1;
				continue;
			}
			if(pos->Need.A==pos->Max.A && pos->Need.B==pos->Max.B && pos->Need.C==pos->Max.C) printf("输入第%d个进程的申请量\n", pos->Id);
			else printf("输入进程%d还需资源量([%d %d %d]个),将其分配给该进程:\n", pos->Id, pos->Need.A, pos->Need.B, pos->Need.C);
			scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C);
            //不满足条件一
            while(pos->Apply.A>pos->Need.A || pos->Apply.B>pos->Need.B || pos->Apply.C>pos->Need.C)
            {
                printf("资源请求量大于资源需求总量,重新输入:\n");
                scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C);
            }
            //不满足条件二,等待
            if(pos->Apply.A>Available.A || pos->Apply.B>Available.B || pos->Apply.C>Available.C)
            {
                pos->State = 'W';
                printf("可利用资源无法满足该资源请求量,进程%d等待\n", pos->Id);
                tmp = pcb;
                //所有进程都为等待,则死锁
				if(tmp->State=='W' && (tmp+1)->State=='W' && (tmp+2)->State=='W')
				{
				    printf("随机分配算法产生死锁!\n");
                    return 0;
				}
                if(pos == pcb+2) pos = pcb-1;
				continue;
            }
            //前两个条件都满足,分配资源
            pos->Allocation.A = pos->Allocation.A+pos->Apply.A;
            pos->Allocation.B = pos->Allocation.B+pos->Apply.B;
            pos->Allocation.C = pos->Allocation.C+pos->Apply.C;
            pos->Need.A = pos->Max.A-pos->Allocation.A;
            pos->Need.B = pos->Max.B-pos->Allocation.B;
            pos->Need.C = pos->Max.C-pos->Allocation.C;
            Available.A = Available.A-pos->Apply.A;
            Available.B = Available.B-pos->Apply.B;
            Available.C = Available.C-pos->Apply.C;
            printf("分配给进程%d[%d,%d,%d]个资源,还需[%d,%d,%d]个资源.\n", pos->Id, pos->Apply.A, pos->Apply.B, pos->Apply.C, pos->Need.A, pos->Need.B, pos->Need.C);
            print();
            //占有的等于总需求,此进程完成
            if(pos->Allocation.A==pos->Max.A && pos->Allocation.B==pos->Max.B && pos->Allocation.C==pos->Max.C) //占有的等于总需求
            {
                pos->State = 'E';
                Available.A += pos->Allocation.A;
                Available.B += pos->Allocation.B;
                Available.C += pos->Allocation.C;
                pos->Allocation.A = pos->Allocation.B = pos->Allocation.C = 0;
                printf("进程[%d]已得到全部资源并释放了占有的资源!\n", pos->Id);
                print();
                if(pos == pcb+2) pos = pcb-1;
            }
            tmp = pcb;
            if(tmp->State=='E' && (tmp+1)->State=='E' && (tmp+2)->State=='E')//进程处于完成态
            {
                printf("随机分配算法没有产生死锁!\n");
                print();
                return 0;
            }
            else
            {
                if(pos == pcb+2) pos = pcb-1;
                continue;
            }
		}
		else if(pos->State == 'W') //等待状态的进程
		{
            if(Available.A>pos->Apply.A && Available.A>=0 && Available.B>pos->Apply.B && Available.B>=0 && Available.C>pos->Apply.C && Available.C>=0)
            {
                pos->State = 'R';
                pos--;
            }
            else
            {
                if(pos == pcb+2) pos = pcb-1;
                continue;
            }
		}
	}
}


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");
        scanf("%d", &n);
		printf("\n");
		if(n == 1)
        {
            InitPCB();
            print();
            bank();
        }
        else if(n == 2)
        {
            InitPCB();
            print();
            random();
        }
        else if(n == 0)
        {
            printf("感谢使用!\n");
            exit(0);
        }
        else printf("选择错误,请重新选择!\n");
	}
	return 0;
}


再附上一组测试数据:

      Max Allocation Need    Available
P1  7 5 3    0 1 3        7 4 0    3 3 2
P2  4 3 3    4 1 1        0 2 2
P3  3 0 6    3 0 1        0 0 5

调试结果部分示例:

操作系统课程设计-银行家算法与随机分配算法_第1张图片


操作系统课程设计-银行家算法与随机分配算法_第2张图片


操作系统课程设计-银行家算法与随机分配算法_第3张图片



你可能感兴趣的:(操作系统,算法,优化,作业&&比赛)