银行家算法 c语言

操作系统学习之银行家算法,c语言代码实现:

本人原创代码,如果有什么错误的地方,欢迎大佬指正!

#include<stdio.h>
#include <malloc.h>
#include<stdlib.h>

typedef struct
{
	int A;//资源A
	int B;//资源B
	int C;//资源C
}PCB;

typedef struct _Node
{
	struct _Node* next;//创建next
	PCB pcb;//类型重命名
}node;

struct node* creat_all() //利用链表创建总资源个数矩阵,此链表头结点不为空!
{
	node* head = malloc(sizeof(node));//创建一个头结点
	scanf("%d%d%d", &head->pcb.A, &head->pcb.B, &head->pcb.C);//输入头结点的成员变量
	return head;//返回head链表
}

struct node* creat_need(int count)//利用链表创建最大需求矩阵,此链表头结点为空!
{
	node* head = malloc(sizeof(node));
	head->next = NULL;//将头节点赋予空值
	node* move = head;//用move指针指向头结点
	
	for (int i = 0; i < count; i++)
	{
		node* fresh = malloc(sizeof(node));//创建临时指针fresh
		fresh->next = NULL;//fresh直接下一个结点为空
		move->next = fresh;//将fresh指向move的下一个结点
		scanf("%d%d%d", &fresh->pcb.A, &fresh->pcb.B, &fresh->pcb.C);//输入该结点的成员变量
		move = fresh;//move指向fresh所在位置的结点,即将move向后移动一个结点
	}
	return head;
}

//创建资源经过分配后各类资源剩余的矩阵
struct node* surp(node* p, node* r, int n) {
	node* move = r->next;//因为r链表的头结点为空,所以move指向r头结点的下一个结点
	int a = 0,b=0,c=0;//定义单个整形变量,用于存储各类资源已分配的总数
	int i;
	for ( i = 0; i < n; i++) {
		a = a + move->pcb.A;
		move = move->next;
	}
	move = r->next;
	for (i = 0; i < n; i++) {
		b = b + move->pcb.B;
		move = move->next;
	}
	move = r->next;
	for (i = 0; i < n; i++) {
		c = c + move->pcb.C;
		move = move->next;
	}
	node* head = malloc(sizeof(node));//创建一个链表存储各类资源剩余数量并返回该链表
	head->pcb.A = p->pcb.A - a;
	head->pcb.B = p->pcb.B - b;
	head->pcb.C = p->pcb.C - c;
	return head;
}

struct node* need(node*q,node*r,int count) {//创建一个链表存储各个进程被分配后还需要的各类资源数量
	node* head = malloc(sizeof(node));
	head->next = NULL;
	node* move = head;//move指向该链表的头结点
	node* temp = q->next;//temp指向链表q的首结点,q链表头结点为空
	node* temb = r->next;//temb指向链表r的首结点,r链表头结点为空
	for (int i = 0; i < count; i++)//此过程与前面创建最大需求矩阵类似
	{
		node* fresh = malloc(sizeof(node));//创建临时变量fresh存储各个进程被分配后还需要的各类资源数量
		fresh->next = NULL;
		move->next = fresh;
		fresh->pcb.A = temp->pcb.A - temb-> pcb.A;
		fresh->pcb.B = temp->pcb.B - temb->pcb.B;
		fresh->pcb.C = temp->pcb.C - temb->pcb.C;
		temp = temp->next;
		temb = temb->next;
		move = fresh;
	}
	return head;
}

//创建一个输出函数,分别输出最大需求矩阵、已分配资源数目矩阵以及各个进程被分配后还需要的各类资源数量的矩阵
void print(node*q,node*r,node*v,int count) {
	printf("		MAX	        Alloction	Need\n");
	node* move = q->next;
	node* temp = r->next;
	node* temb = v->next;
	for (int i = 0; i < count; i++) {
		printf("P%d		%d %d %d		%d %d %d		%d %d %d\n", i,move->pcb.A,  move->pcb.B, move->pcb.C,temp->pcb.A,temp->pcb.B, temp->pcb.C,temb->pcb.A, temb->pcb.B, temb->pcb.C);
		move = move->next;
		temp = temp->next;
		temb = temb->next;
	}
}

void banker(node*r,node*u,node*v,int count) {//创建一个模拟银行家算法的函数
	node* move = u;
	int sum=0;//定义一个整型变量sum进行计数
	for (int i = 0; i < count; i++) {
		node* temp = v->next;
		node* temb = r->next;
		int n = 0;//创建整型变量n用于计算各个进程的序列号
		while (temb != NULL) {			
			if (move->pcb.A >= temp->pcb.A && move->pcb.B >= temp->pcb.B && move->pcb.C >= temp->pcb.C) {//如果满足条件就输出该进程的序列号
				move->pcb.A += temb->pcb.A;
				move->pcb.B += temb->pcb.B;
				move->pcb.C += temb->pcb.C;
				temp->pcb.A += 100;//此处因为该位置进程安全并且即将输出,+100后就不会满足判断条件,让第二次循环跳过该位置的进程
				temp->pcb.B += 100;//当然,当各类资源数目大于100时,+100就不适合,此处可以随条件变化更改
				temp->pcb.C += 100;
				printf("P%d ", n);
				sum++;//每当输出一次,sum+1
				break;
			}
			else {//如果不满足条件就使指针指向当前结点的下一个结点
				temp = temp->next;
				temb = temb->next;
				n = n + 1;
			}
		}
	}
	if (sum != 5) {//如果sum不等于5,即没有输出五次,表明存在一些进程不安全,无法输出安全序列
		printf("无 因为此序列不安全\n");
		exit(-1);//退出程序
	}
}

//创建一个链表,存储经过分配给进程申请的资源后所剩余的各个资源数目
struct node* surp_1(node*u,node*g) {
	node* head = malloc(sizeof(node));
	if (g->pcb.A>u->pcb.A||g->pcb.B>u->pcb.B||g->pcb.C>u->pcb.C) {//如果申请的资源数目大于剩余资源数目,则退出程序
		printf("请求资源大于系统可用资源,不予分配!\n");
		exit(-1);
	}
	//将经过分配给进程申请的资源后所剩余的各个资源数目存入head所指的链表
	head->pcb.A = u->pcb.A - g->pcb.A;
	head->pcb.B = u->pcb.B - g->pcb.B;
	head->pcb.C = u->pcb.C - g->pcb.C;
	return head;
}

struct node* new_Alloc(node*r,node*g,int num) {//创建一个函数,并存储经过分配给进程申请的资源后所得出的资源分配矩阵
	node* move = r->next;
	for (int i = 0; i < num;i++) {
		move = move->next;
	}
	move->pcb.A += g->pcb.A;
	move->pcb.B += g->pcb.B;
	move->pcb.C += g->pcb.C;
	return r;
}

int main() {
	printf("-------数据初始化开始,默认系统有A、B、C三种资源-------\n");
	node*p;//创建指针p
	printf("请输入各个资源的实例个数\n");
	p=creat_all();//p指向存储资源总数矩阵的地址
	node* q;//创建指针q
	printf("请输入进程数量:\n");
	int count;
	scanf("%d", &count);
	printf("请输入各进程对每类资源的最大需求矩阵MAX\n");
	q = creat_need(count);//q指向存储最大需求矩阵的地址
	node* r;//创建指针r
	printf("请输入各个进程已分配的每类资源的数目矩阵Allocation\n");
	r= creat_need(count);//利用创建最大需求矩阵的函数,创建已分配资源数目的矩阵
	node* u;//创建指针u
	u=surp(p, r,count);//u指向资源经过分配后各类资源剩余的矩阵
	printf("系统目前可用资源\n");
	printf("A B C\n");
	printf("%d %d %d\n", u->pcb.A, u->pcb.B, u->pcb.C);
	node* v;//创建指针v
	v = need(q, r,count);//u指向各个进程被分配后还需要的各类资源数量的矩阵
	printf("系统当前资源情况如下\n");
	print(q, r,v,count);//将指针q、r、v、count传入print函数
	printf("安全序列为:");
	banker(r, u, v, count);//将指针r、u、v、count传入banker函数
	printf("\n");
	printf("请输入要申请资源的进程编号0-4:\n");
	int num;
	scanf("%d", &num);
	node* g;//创建指针g 
	printf("请输入进程P%d要申请的资源个数:\n",num);
	printf("A B C\n");
	g = creat_all();//利用创建总资源数的函数创建该进程申请各个资源的数目
	node* u1;//创建指针u1
	u1 = surp(p, r, count); // u1与u指向相同的资源经过初始分配后各类资源剩余的矩阵
	node* s;//创建指针s
	s=surp_1(u1,g);//s指向经过进程申请资源分配后所剩余的资源数目矩阵的地址
	printf("目前系统可用资源为:\n");
	printf("A B C\n");
	printf("%d %d %d\n", s->pcb.A, s->pcb.B, s->pcb.C);//输出经过进程申请资源分配后所剩余的资源数目
	node* r1;//创建指r1
	r1=new_Alloc(r,g, num);//r1指向加上某一进程申请资源后的资源分配矩阵
	node* v1;//创建指针v1
	v1 = need(q,r1, count);//v1指向某一进程申请资源后各个进程还需要的资源数目
	printf("系统当前资源情况如下\n");
	print(q, r1, v1, count);//将指针q、r1、v1、count传入print函数
	printf("安全序列为:");
	banker(r1, s, v1, count);//将指针r1、s、v1、count传入banker函数
}

这是第一种正常输入:

 第二种输入为申请资源大于剩余可用资源时:

第三种输入为当系统不安全时:

  • 11
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一串平凡的代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值