7-1 银行家算法--安全性检查 (20 分)(思路+详解+知识分析)宝 你今天 AC了吗

一:前言

停更一周了,在这一周里,我每时每刻都在 想这我这 29个粉丝,庆幸教师资格证终于结束了,贴心杰又可以天天更新博客了
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,I am come back;

二:题目:

输入N个进程(N<=100),以及M类资源(M<=100),初始化各种资源的总数,T0时刻资源的分配情况。判断T0时刻是否安全。例如: 假定系统中有5个进程{P0,P1,P2,P3,P4}和三类资源{A,B,C},各种资源的数量分别为10、5、7,在T0时刻的资源分配图如下:
在这里插入图片描述
输入格式:
第一行输入进程数量N,第二行输入资源类数M,第三行输入M类资源个类资源的总数,以下N行分别输入每个进程的名字,该进程对M类资源的最大需求以及已分配资源。

输出格式:
输出T0时刻系统的状态。若安全,输出“找到安全序列,处于安全状态。”否则,输出“找不到安全序列,处于不安全状态。”

输入样例:
在这里给出一组输入。例如:

5
3
10 5 7
P0 7 5 3 0 1 0
P1 3 2 2 2 0 0
P2 9 0 2 3 0 2
P3 2 2 2 2 1 1
P4 4 3 2 0 0 2

输出样例:
在这里给出相应的输出。例如:

name max allocation need available
P0 7 5 3 | 0 1 0 | 7 4 3 | 3 3 2
P1 3 2 2 | 2 0 0 | 1 2 2 |
P2 9 0 2 | 3 0 2 | 6 0 0 |
P3 2 2 2 | 2 1 1 | 0 1 1 |
P4 4 3 2 | 0 0 2 | 4 3 0 |
找到安全序列,处于安全状态。

三:思路

思路:
1.首先我们进行安全性算法是为了预防死锁,再解释一下死锁 比如
1>:在系统中有两个进程p1,p2 和两个资源r1(扫描仪),r2(刻录机)
p1和p2都需要将扫描的文档通过刻录机刻录到CD盘上,
2>:进程p1先请求资源r1成功,进程p2请求资源r2成功,那么接下来,
p1又申请了r2资源 p2申请了r1资源,那么此时p1和p2都在等对方
释放资源那么就会发生死锁,两个进程都无法进行下去
2.那么安全性算法就是使系统在分配资源时候一直处在安全的状态(即不会发生死锁)
那么我们在分配资源的时候就有了算法,即最终分配给各个进程的资源,都不会影响到
整个系统的安全状态,这时会出现一个进程的执行序列
3.具体解释算法过程
1>:几个变量
Max:一个进程所需的最大资源量
Allocation:系统已经给其分配了多少资源
Need:这个进程还需要多少资源
Available:这个系统还剩多少资源
2>:刚开始设置work = Available 将所有进程设置为 finish = false (相当于定义一个flag)

3>:找一个进程满足下列的条件 
finish = false
    need <= work(需要的资源得比系统剩余的要少)
4>:如果 3>的条件满足的话,我们就需要 
将work += Allocation (每个进程执行完后需要释放资源)
finish = true (代表该进程完成)
返回步骤 3>继续寻找满足上诉条件的进程 

5>:思考如何判定此时的系统状态是安全还是不安全的
安全:如果 3>的条件不满足 即此时的所有进程的 finsh = true 说明了所有的进程已经完成
不安全: 我们已经判断了所有的finish = false 的进程,但是仍未找到满足条件的
need < work 那么可以判定此状态为 不安全的状态
4.处理数据
1>:这里我们选取的数据结构是结构体数组因为一个进程他对应好多属性,所以选取的是结构体
在结构体的属性当中 我们设置一个 max[] 和 allocation[] 目的是存放多个不同类型资源
2>:关于node[i].a[j],node[i].b[j],node[i].c[j]的理解,就是3个二维数组 就是这样的

四:先说坑

1.这个题无语了简直了真是,不,应该是PTA这个平台让我真的无语了,我定义了一个变量 cnt 但我并未初始化为0 ,我在DEV-C中测试了好多数据其实也无妨正确结果,但是在PTA中提交一直显示答案错误,而且测试样例一直输出 找不到安全序列,真的一上午我真的想砸电脑,什么呀!! 最后坚持不懈,不信邪,终于让我发现一个大毛病,原来在PTA上变量必须初始化,否则系统自动给你赋值一个很大数 ,但在DEV-C上却没有任何问题
2.这个题还需要的是无论 是否可以得到安全序列,其都必须将其系统中各个进程的状态输出来

五:上码

/**
	思路:1.首先我们进行安全性算法是为了预防死锁,再解释一下死锁 比如
			1>:在系统中有两个进程p1,p2 和两个资源r1(扫描仪),r2(刻录机)
				p1和p2都需要将扫描的文档通过刻录机刻录到CD盘上, 
			2>:进程p1先请求资源r1成功,进程p2请求资源r2成功,那么接下来,
				p1又申请了r2资源  p2申请了r1资源,那么此时p1和p2都在等对方
				释放资源那么就会发生死锁,两个进程都无法进行下去
		 2.那么安全性算法就是使系统在分配资源时候一直处在安全的状态(即不会发生死锁)
		 	那么我们在分配资源的时候就有了算法,即最终分配给各个进程的资源,都不会影响到
			 整个系统的安全状态,这时会出现一个进程的执行序列
		 3.具体解释算法过程
			1>:几个变量
				Max:一个进程所需的最大资源量
				Allocation:系统已经给其分配了多少资源
				Need:这个进程还需要多少资源
				Available:这个系统还剩多少资源
			2>:刚开始设置work = Available  将所有进程设置为 finish = false (相当于定义一个flag)
			  
			3>:找一个进程满足下列的条件 
				 finish = false
			      need <= work(需要的资源得比系统剩余的要少)
			4>:如果 3>的条件满足的话,我们就需要 
				将work += Allocation (每个进程执行完后需要释放资源)
				finish = true (代表该进程完成)
				返回步骤 3>继续寻找满足上诉条件的进程 
			
			5>:思考如何判定此时的系统状态是安全还是不安全的 
				安全:如果 3>的条件不满足 即此时的所有进程的 finsh = true 说明了所有的进程已经完成
				不安全: 我们已经判断了所有的finish = false 的进程,但是仍未找到满足条件的
						need < work 那么可以判定此状态为 不安全的状态 
					
			
			,否则
				那么就是说明该系统处在不安全的状态(即会发生死锁)
					  
		4.处理数据 
			1>:这里我们选取的数据结构是结构体数组因为一个进程他对应好多属性,所以选取的是结构体	    		 			 
				在结构体的属性当中 我们设置一个 max[] 和 allocation[] 目的是存放多个不同类型资源 
			2>:关于node[i].a[j],node[i].b[j],node[i].c[j]的理解,就是3个二维数组 就是这样的  

*/ 


#include<bits/stdc++.h>
using namespace std;


struct Node{
	string processName;//进程名	
	int a[100];//Max  
	int b[100];//allocation 
	int c[100];//need 
	bool finish;
		
}node[1000];


//关于重写 sort方法中的两个参数 都表示是一个结构体(即我们需要用两个结构体当中的数据进行比较) 
bool sort_c(Node node1,Node node2){
	return node1.c[0] < node2.c[0];
}

int main(){
	
	int N,M;
	int cnt = 0;//用于记进程完成的个数 
	vector<int>v1;//存总的资源总量 
	vector<int>v2;//存need需要的资源 
	vector<int>v3;//记录最后需要输出的Available 
	
	cin >> N >> M;
	
	for(int i = 0; i < M; i++){
		
		int resources;
		cin >> resources;
		v1.push_back(resources); 

	}
	
	for(int i = 0; i < N; i++){
		
		cin >> node[i].processName;
		
		//输入Max 
		for(int j = 0; j < M; j++){
			
			cin >> node[i].a[j];
			
		}
		//输入allocation 
		for(int j = 0; j < M; j++){
			
			cin  >> node[i].b[j]; 
			
			v1[j] -= node[i].b[j];//这里是每次减去分配的资源 那么剩下的最后就是  available 
		}
		//求取need
		for(int j = 0; j < M; j++){
			node[i].c[j] = node[i].a[j] - node[i].b[j];
		} 
		
		node[i].finish = false;//将每个进程初始状态设为 false 
		
	}      
	
	for(int i = 0; i < M; i++){
		v3.push_back(v1[i]);
	} 
	
//	sort(node,node+N,sort_c);
	
	//算法核心部分 
	for(int i = 0; i < N; i++){
		
		int count = 0;
		for(int j = 0; j < M; j++){
			
			if(node[i].c[j] <= v1[j]){
				count++;
			
			}else{
				break;//只要有一个不合适就 break 出去 
			}				
		}
				
		if(node[i].finish == false && count == M) {//count == M说明剩余的各个资源总量大于该进程的所需要的 
					
			for(int j = 0; j < M; j++){
				
				v1[j] += node[i].b[j];//那么此时剩余的资源总量为原来的加上 该进程释放其占有的资源
		 
			}	
			
			node[i].finish = true; 
			
			cnt++;//记录完成进程的个数 
			
		//	cout << node[i].processName << ' ';
				
			//此处牛逼之处在于 只要我们找到满足条件的就从-1开始继续寻找满足条件的 
			i = -1; 
			
			
		}					
	}
	
	//	cout << endl;

	int flag = 0;
    
		cout << "name max allocation need available" << endl;
		
		for(int i = 0; i < N; i++){
			
			cout << node[i].processName << ' ';
			for(int j = 0; j < M; j++){
			 
			 cout << node[i].a[j] << ' ';			
			}			
			
			cout << "| ";
			
			for(int j = 0; j < M; j++){
			 
			 cout << node[i].b[j] << ' ';			
			}
			
			cout << "| ";
			
			for(int j = 0; j < M; j++){
			 
			 cout << node[i].c[j] << ' ';			
			}
			
			cout << "|";
			
			if(flag == 0){
			
               
				for(int j = 0; j < M; j++){
				 
                    if(j == 0)
                        cout << ' ' <<v3[j];
                    else
				        cout << ' ' <<v3[j] ;				 			
				}	
				
				flag = 1;		
			}	
			
			
			cout << endl;	
		}
    
   if(cnt == N){	
		cout << "找到安全序列,处于安全状态。";
				
	}else{
		cout << "找不到安全序列,处于不安全状态。";
	} 
	
	
	
//	for(int i = 0; i < M; i++){
//		cout << v1[i] << ' ';
//	} 
		
//  验证数据	
//	for(int i = 0; i < N; i++){
//		
//		cout << node[i].processName << ' ';
//		
//		for(int j = 0; j < M; j++){
//			
//			cout << node[i].c[j] << ' '; 
//		}
//		cout << endl;
//	}
	 
	
	
}



//name max allocation need available
//P0 7 5 3 | 0 1 0 | 7 4 3 | 3 3 2
//P1 3 2 2 | 2 0 0 | 1 2 2 |
//P2 9 0 2 | 3 0 2 | 6 0 0 |
//P3 2 2 2 | 2 1 1 | 0 1 1 |
//P4 4 3 2 | 0 0 2 | 4 3 0 |
//找到安全序列,处于安全状态。


//5
//3
//10 5 7
//P0 8 6 3 0 1 0
//P1 3 2 2 2 0 0
//P2 9 0 2 3 0 2
//P3 2 2 2 2 1 1
//P4 4 3 2 0 0 2


//5
//3
//6 3 5
//P0 7 5 3 0 1 0
//P1 3 2 2 2 0 0
//P2 9 0 2 3 0 2
//P3 2 2 2 2 1 1
//P4 4 3 2 0 0 2

//5
//4
//3 14 12 12
//p0 0 0 1 2 0 0 1 2
//p1 1 7 5 0 1 0 0 0
//p2 2 3 5 6 1 3 5 4
//p3 0 6 5 2 0 6 3 2
//p4 0 6 5 6 0 0 1 4 








 

在这里插入图片描述
最后 再唠叨一句 ,记得加油宝!! 我们共勉 共同进步!!!

  • 13
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
银行家算法用于避免死锁,确保系统资源的配是安全的。下面是一个简单的银行家算法的C语言代码实现,该代码实现了以下函数: - `request_resources()`:请求资源 - `release_resources()`:释放资源 - `is_safe()`:判断当前状态是否安全 注意,这里的资源是指系统中的各种资源,如内存、I/O设备等。每个进程都会请求一定数量的资源,并在使用完这些资源后释放它们。 ```c #include <stdio.h> #define MAX_PROCESSES 10 #define MAX_RESOURCES 10 int available[MAX_RESOURCES]; int maximum[MAX_PROCESSES][MAX_RESOURCES]; int allocation[MAX_PROCESSES][MAX_RESOURCES]; int need[MAX_PROCESSES][MAX_RESOURCES]; int num_processes; int num_resources; int request_resources(int pid, int request[]) { int i; for (i = 0; i < num_resources; i++) { if (request[i] > need[pid][i]) { return -1; } if (request[i] > available[i]) { return -1; } } for (i = 0; i < num_resources; i++) { available[i] -= request[i]; allocation[pid][i] += request[i]; need[pid][i] -= request[i]; } if (is_safe()) { return 0; } else { for (i = 0; i < num_resources; i++) { available[i] += request[i]; allocation[pid][i] -= request[i]; need[pid][i] += request[i]; } return -1; } } int release_resources(int pid, int release[]) { int i; for (i = 0; i < num_resources; i++) { available[i] += release[i]; allocation[pid][i] -= release[i]; need[pid][i] += release[i]; } return 0; } int is_safe() { int i, j, k; int work[MAX_RESOURCES]; int finish[MAX_PROCESSES]; for (i = 0; i < num_resources; i++) { work[i] = available[i]; } for (i = 0; i < num_processes; i++) { finish[i] = 0; } for (i = 0; i < num_processes; i++) { if (finish[i] == 0) { for (j = 0; j < num_resources; j++) { if (need[i][j] > work[j]) { break; } } if (j == num_resources) { finish[i] = 1; for (k = 0; k < num_resources; k++) { work[k] += allocation[i][k]; } i = -1; } } } for (i = 0; i < num_processes; i++) { if (finish[i] == 0) { return 0; } } return 1; } ``` 在上面的代码中,`available`数组表示每个资源当前可用的数量;`maximum`数组表示每个进程最多需要的每个资源的数量;`allocation`数组表示每个进程已配的资源数量;`need`数组表示每个进程还需要的资源数量。 `request_resources()`函数用于请求资源。如果请求的资源超过了进程所需要的资源数量或者超过了当前可用的资源数量,该函数将返回-1,表示请求失败。否则,该函数将配请求的资源,并调用`is_safe()`函数判断当前状态是否安全。如果是安全的,该函数将返回0,否则将释放配的资源,并返回-1。 `release_resources()`函数用于释放资源。该函数将释放进程已配的资源,并更新`available`、`allocation`和`need`数组。 `is_safe()`函数用于判断当前状态是否安全。该函数首先初始化`work`数组为当前可用的资源数量,`finish`数组为0。然后对于每个未完成的进程,检查它是否需要的每个资源数量都小于等于`work`数组中的相应资源数量。如果是,将该进程标记为完成,并将它已配的资源释放到`work`数组中。如果所有进程都完成了,返回1,否则返回0。 在实际使用中,需要根据具体情况修改上面的代码。例如,可以在`request_resources()`和`release_resources()`函数中添加一些输出语句,以便调试和测试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天天向上的菜鸡杰!!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值