精华内容
下载资源
问答
  • 实现资源的分配,预防死锁的出现。寻找安全序列,合理安排资源数。
  • 用递归方式实现将所有的安全序列按序输出的银行家算法;进程数目和资源种类用宏定义控制。
  • 如题:现有以下资源分配情况(摘自操作系统第三版---西安电子科技出版社) Process Allocation Need Available P(0) 0032 0012 1622 P(1) 1000 1750 ...(还有,这里不写了),那么请问这些都是安全序列吗?
  • } bool security_check(){ // 确认安全序列的存在性 # 如果要查找并输出所有可能的安全序列不能用这个方法 vector<unsigned int> Work(Available); vector<bool> Finish(n,false); int passed = 0; secure_seq....

    copyright© Author: skysys 仅发于CSDN: skysys.blog.csdn.net

    题目2 银行家算法编程

    目的:

    熟悉银行家算法,加深死锁有关概念的理解。

    内容:

    编制银行家算法通用程序,并检测思考题中所给状态的安全性。
    要求:
    (1) 下列状态是否安全?(三个进程共享12个同类资源)
    进程 已分配资源数 最大需求数
    1 1 4 (状态a)
    2 4 4
    3 5 8

    1 1 4
    2 4 6 (状态b)
    3 6 8

    (2) 考虑下列系统状态
    分配矩阵 最大需求矩阵 可用资源矩阵
    0 0 1 2 0 0 1 2 1 5 2 0
    1 0 0 0 1 7 5 0
    1 3 5 4 2 3 5 6
    0 6 3 2 0 6 5 2
    0 0 1 4 0 6 5 6
    问系统是否安全?若安全就给出所有的安全序列。若进程2请求(0420),可否立即分配?


    自编算法伪码(书上的伪码感觉emm很奇怪,也可能是我奇怪吧)

    	Available[j] K
    	Max[i,j] process i need resource j 
    	Allocation[i,j]  process i allocated resource j
    	Need[i,j] = max[i,j] - allocation[i,j]
    
    when request[i] arrived then
    for each request[i,j]
    	if request[i,j] <= need[i,j] // 合理性审查 (程序可能出错,导致发出异常申请,这种情况直接把申请拦截) 
    		while for each j if exists request[i,j] > available[j]: waiting // 安全性审查 
    		// 尝试分配 
    		available[j] := available[j] - request[i,j] 
    		allocation[i,j] := allocation[i,j] + request[i,j]
    		need[i,j] := need[i,j] - request[i,j]
    		// 分配之后剩下的是否有解 
    		do secrurity_check() 
    			if passed: return true;
    			else: rollback; return false // 回溯(回滚)
    	else error
    	
    	fuction security_check  // 进行本次分配之后资源分配图是否仍然有解 
    		work := available // 因为要模拟剩余变量的修改 
    		finish[i] := false // 初始化无解 
    		while exists finish[i] = false and  for each j need[i,j] <= work[j]
    			for each j work[j] := work[j] + allocation[i,j]
    			finish[i] := true
    		check if forall i, finish[i] = true
    			if true: succeed
    			else: error
    

    文末参考文献[1]对银行家算法提出了一个可行的优化(下面的代码没有加):
    在进行试探性资源分配之后在安全检查之前,如果当前试探性分配给进程i资源之后,其Need[i][j]<=Available[i][j]仍然成立那么当前分配不用经过检查就可以一定证明是有效的。可以省掉这种情况的安全检查。


    由于ppt上是这样的表:
    在这里插入图片描述
    所以初始化顺序是先AVAL
    然后对每个process 依次读入MAX\ALLO\NEED

    C++实现通用性的银行家算法
    输入有点蠢,Need矩阵其实可以计算,不用输入得到,我懒得改了。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m; // n - process  m - resources
    vector<unsigned int> Available;
    vector<vector<unsigned int>> Max,Allocation,Need;
    vector<int> secure_seq;
    inline void initialize(string filename){
    	ifstream  fin;
    	fin.open(filename);
    	fin>>n>>m;
    	unsigned int t;
    	for(int i=0;i<m;i++){ fin>>t; Available.push_back(t); }
    	for(int i=0;i<n;i++){
    		vector<unsigned int> Max_t;
    		for(int j=0;j<m;j++){ fin>>t; Max_t.push_back(t); }
    		Max.push_back(Max_t);
    		
    		vector<unsigned int> Allo_t;
    		for(int j=0;j<m;j++){ fin>>t; Allo_t.push_back(t); }
    		Allocation.push_back(Allo_t);
    		
    		vector<unsigned int> Need_t;
    		for(int j=0;j<m;j++){ fin>>t; Need_t.push_back(t); }
    		Need.push_back(Need_t); 
    	}
    	fin.close();
    }
    
    
    
    bool security_check(){ // 确认安全序列的存在性 # 如果要查找并输出所有可能的安全序列不能用这个方法 
    	vector<unsigned int> Work(Available);
    	vector<bool> Finish(n,false);
    	int passed = 0;
    	secure_seq.clear();
    	bool isNewPassed = true;
    	while(isNewPassed){
    		isNewPassed = false;
    		for(int i=0;i<n;i++)if(!Finish[i]){
    			bool ok = true;
    			for(int j=0;j<m;j++)if(Need[i][j]>Work[j]){ok = false; break;}
    			if(ok){
    				for(int j=0;j<m;j++)Work[j] += Allocation[i][j];
    				Finish[i] = true;
    				passed++;
    				isNewPassed = true;
    			}	
    		}
    	}
    	return passed == n;
    }
    // 找到并输出所有的安全序列 undo 
    
    int id; vector<unsigned int> request;
    void banker(){
    	for(int i=0;i<m;i++) if(request[i]>Need[id][i]){ 
    		cout<<"Error#申请资源超出声明的需要资源"<<endl;
    		return;
    	}
    	for(int i=0;i<m;i++) if(request[i]>Available[i]){
    		cout<<"Error#当前申请超出当前空余的资源,申请被搁置"<<endl;
    		return;
    	}
    	// 模拟分配 
    	for(int i=0;i<m;i++){
    		Available[i] -= request[i];
    		Allocation[id][i] += request[i];
    		Need[id][i] -= request[i];
    	}
    	if(security_check())cout<<"Success#成功分配"<<endl;
    	else cout<<"Error#分配失败,未通过安全检查"<<endl;
    }
    int main(){
    	initialize("banker_test_data3.txt");
    	int t;
    	if(security_check())cout<<"Success#当前处于安全状态"<<endl;
    	else { cout<<"Error#当前处于不安全状态"<<endl; exit(1);} 
    	while(1){
    		cout<<endl<<"请依次输入资源申请: id x0 x1 ... [id表示进程编号,后面表示对资源的申请]"<<endl<<"Input:";
    		cin>>id;
    		request.clear();
    		for(int i=0;i<m;i++){
    			cin>>t; request.push_back(t);
    		}
    		banker();
    	}
    	return 0;
    }
    
    

    增加输出安全序列的功能:

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m; // n - process  m - resources
    vector<unsigned int> Available;
    vector<vector<unsigned int>> Max,Allocation,Need;
    inline void initialize(string filename){
    	ifstream  fin;
    	fin.open(filename);
    	fin>>n>>m;
    	unsigned int t;
    	for(int i=0;i<m;i++){ fin>>t; Available.push_back(t); }
    	for(int i=0;i<n;i++){
    		vector<unsigned int> Max_t;
    		for(int j=0;j<m;j++){ fin>>t; Max_t.push_back(t); }
    		Max.push_back(Max_t);
    		
    		vector<unsigned int> Allo_t;
    		for(int j=0;j<m;j++){ fin>>t; Allo_t.push_back(t); }
    		Allocation.push_back(Allo_t);
    		
    		vector<unsigned int> Need_t;
    		for(int j=0;j<m;j++){ fin>>t; Need_t.push_back(t); }
    		Need.push_back(Need_t); 
    	}
    	fin.close();
    }
    
    vector<int> secure_seq;
    // ÕÒµ½²¢Êä³öËùÓеݲȫÐòÁÐ
    bool findSecureSeqence(vector<unsigned int>& Work,vector<bool>& Finish,int cur){
    	if(cur == n){
    		cout<<"°²È«ÐòÁÐ#";	
    		for(int i=0;i<n-1;i++)cout<<secure_seq[i]<<"->";
    		cout<<secure_seq[n-1]<<endl;
    		return true;
    	}
    	bool flag = false;
    	for(int i=0;i<n;i++)if(!Finish[i]){
    		bool ok = true; for(int j=0;j<m;j++) if(Need[i][j]>Work[j]){ok = false; break;}
    		if(ok){
    			for(int j=0;j<m;j++)Work[j] += Allocation[i][j];
    			Finish[i] = true; secure_seq.push_back(i);
    			if(findSecureSeqence(Work,Finish,++cur)) flag = true;
    			for(int j=0;j<m;j++)Work[j] -= Allocation[i][j];
    			Finish[i] = false; secure_seq.pop_back();
    		}
    	}
    	return flag;		
    } 
    
    
    bool security_check(bool printSequence=false){ // È·ÈÏ°²È«ÐòÁеĴæÔÚÐÔ # Èç¹ûÒª²éÕÒ²¢Êä³öËùÓпÉÄܵݲȫÐòÁв»ÄÜÓÃÕâ¸ö·½·¨ 
    	vector<unsigned int> Work(Available);
    	vector<bool> Finish(n,false);
    	int passed = 0;
    	secure_seq.clear();	
    	if(printSequence)return findSecureSeqence(Work,Finish,0);
    
    	bool isNewPassed = true;
    	while(isNewPassed){
    		isNewPassed = false;
    		for(int i=0;i<n;i++)if(!Finish[i]){
    			bool ok = true;
    			for(int j=0;j<m;j++)if(Need[i][j]>Work[j]){ok = false; break;}
    			if(ok){
    				for(int j=0;j<m;j++)Work[j] += Allocation[i][j];
    				Finish[i] = true;
    				passed++;
    				isNewPassed = true;
    			}	
    		}
    	}
    	return passed == n;
    }
    
    int id; vector<unsigned int> request;
    void banker(){
    	for(int i=0;i<m;i++) if(request[i]>Need[id][i]){ 
    		cout<<"Error#ÉêÇë×ÊÔ´³¬³öÉùÃ÷µÄÐèÒª×ÊÔ´"<<endl;
    		return;
    	}
    	for(int i=0;i<m;i++) if(request[i]>Available[i]){
    		cout<<"Error#µ±Ç°ÉêÇ볬³öµ±Ç°¿ÕÓàµÄ×ÊÔ´£¬ÉêÇë±»¸éÖÃ"<<endl;
    		return;
    	}
    	// Ä£Äâ·ÖÅä 
    	for(int i=0;i<m;i++){
    		Available[i] -= request[i];
    		Allocation[id][i] += request[i];
    		Need[id][i] -= request[i];
    	}
    	if(security_check())cout<<"Success#³É¹¦·ÖÅä"<<endl;
    	else cout<<"Error#·ÖÅäʧ°Ü£¬Î´Í¨¹ý°²È«¼ì²é"<<endl;
    }
    int main(){
    	initialize("banker_test_data3.txt");
    	int t;
    	if(security_check(true))cout<<"Success#µ±Ç°´¦ÓÚ°²È«×´Ì¬"<<endl;
    	else { cout<<"Error#µ±Ç°´¦ÓÚ²»°²È«×´Ì¬"<<endl; exit(1);} 
    	while(1){
    		cout<<endl<<"ÇëÒÀ´ÎÊäÈë×ÊÔ´ÉêÇë: id x0 x1 ... [id±íʾ½ø³Ì±àºÅ,ºóÃæ±íʾ¶Ô×ÊÔ´µÄÉêÇë]"<<endl<<"Input:";
    		cin>>id;
    		request.clear();
    		for(int i=0;i<m;i++){
    			cin>>t; request.push_back(t);
    		}
    		banker();
    	}
    	return 0;
    }
    

    测试数据

    5 3
    3 3 2
    7 5 3 0 1 0 7 4 3
    3 2 2 2 0 0 1 2 2
    9 0 2 3 0 2 6 0 0
    2 2 2 2 1 1 0 1 1
    4 3 3 0 0 2 4 3 1
    

    request手工输入,根据下面的PPT或者自编数据测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述


    参考文献

    [1]李柱,权奇哲.银行家算法的改进[J].中外企业家,2014(06):57.
    [2]《操作系统原理与实践》
    [3] NCEPU 操作系统课程的课件

    展开全文
  • 安全序列

    2020-11-01 14:42:41
    在此次寻找安全序列时,找到的第一个进程为P0,若其运行完毕释放资源后,系统的Available变为多少,请写出详细的过程。 每问2分 ① 可用资源数量 available =[5,6,8,6,4]-[2,2+1+3,1+1+1,1+1+1+2,1+1+1] =[3,0,...

    某系统中有5种资源,数量为[5,6,8,6,4],某个时刻进程和资源的使用情况如下:
    进程名 Allocation Need
    P0 [0,2,1,1,1] [1,0,2,1,1]
    P1 [2,0,1,1,1] [0,3,2,1,0]
    P2 [0,1,0,1,1] [0,3,3,2,2]
    P3 [0,3,1,2,0] [1,0,1,2,1]
    此时系统的可用资源数量Available为多少,按照从P0到P3依次进行的顺序,进行安全性检测找到的第二个满足条件的进程为P3 ,检测后发现系统是不是 安全状态?为什么。若此时进程P0提出申请资源[1,0,0,0,1],假设系统满足其要求后,经检测发现系统
    是不是 安全状态,为什么;在此次寻找安全序列时,找到的第一个进程为P0,若其运行完毕释放资源后,系统的Available变为多少,请写出详细的过程。
    每问2分
    ① 可用资源数量 available =[5,6,8,6,4]-[2,2+1+3,1+1+1,1+1+1+2,1+1+1]
    =[3,0,5,1,1]
    ② 是;因为[3,0,5,1,1] >[1,0,2,1,1] ,所以第一个执行的是P0,P0执行结束释放全部资源。此时的 可用资源数量 available = [ 3,2,6,2,2] >[ 1,0,1,2,1] 继续执行, P3执行结束释放全部资源。此时的 可用资源数量 available = [3,5,7,4,2] 继续执行P1或P2, 例如P2执行结束释放全部资源。此时的 可用资源数量 available = [3,6,7,5,3] 继续执行P1, 例如P1执行结束释放全部资源。安全。
    ③ 是;执行方法和第二问一致,就直接表示结果 [3,0,5,1,1]–>[ 3,2,6,2,2] -->[3,5,7,4,2]–>[3,6,7,5,3]–>[5,6,8,6,4]
    ④ 执行完P0后,
    应可使用资源为available =[5,6,8,6,4]-[2,1+3,1+1,1+1+2,1+1]
    = [3,2,6,2,2]
    哲学家问题
    假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉
    在这里插入图片描述哲学家(可能会死锁)
    在这里插入图片描述
    哲学家(2的倍数就拿左再右)
    在这里插入图片描述哲学家(4就等着)
    在这里插入图片描述分析:哲学家的死锁是当所有人都拿起自己右边的叉子,那他们就都拿不到自己左面的叉子,造成死锁。

    #define M 5
    sem_t sfork[M];
    void * philosopher(void *p){
    	int id = (int)p;
    	while(1){
    		printf("%d : Think....\n", id);
    		sleep(1);
    		sem_wait(&sfork[id]);
    		sem_wait(&sfork[(id+1)%5]);
    		printf("%d : Eating...\n", id);
    		sleep(1);
    		sem_post(&sfork[id]);
    		sem_post(&sfork[(id+1)%5]);
    	}	return NULL;
    }
    int main(void){	
    	int i;
    	for(i=0;i<M;i++){
    		sem_init(&sfork[i], 0, 1);
    	}
    	pthread_t tid[M];	
    	for(i=0;i<M;i++){
    		pthread_create(&tid[i],NULL,philosopher,i);
    	}	
    	for(i=0;i<M;i++){
    		sem_destroy(&sfork[i]);
    	}
    	
    	for(i=0;i<M;i++){
    		pthread_join(tid[i], NULL);
    	}
    	return 0;
    } 
    

    哲学家优化

    #define M 5
    sem_t sfork[M];
    void * philosopher(void *p){
    	int id = (int)p;
    	while(1){
    		printf("%d : Think....\n", id);
    		sleep(1);
    		if(id%2==0){
    			sem_wait(&sfork[id]);
    			sem_wait(&sfork[(id+1)%5]);
    		}else{
    			sem_post(&sfork[(id+1)%5]);
    			sem_post(&sfork[id]);			
    		}				printf("%d : Eating...\n", id);
    		sem_wait(&sfork[id]);
    		sem_wait(&sfork[(id+1)%5]);	
    		sleep(1);	
    	}
    	return NULL;
    }
    int main(void){	
    	int i;
    	for(i=0;i<M;i++){
    		sem_init(&sfork[i], 0, 1);
    	}
    	pthread_t tid[M];
    	
    	for(i=0;i<M;i++){
    		pthread_treate(&tid[i],NULL,philosopher,i);
    	}	
    	for(i=0;i<M;i++){
    		sem_destroy(&sfork[i]);
    	}
    	
    	for(i=0;i<M;i++){
    		pthread_join(tid[i], NULL);
    	}
    	return 0;
    } 
    
    展开全文
  • 银行家算法——输出所有安全序列

    千次阅读 2019-11-09 23:37:42
    思路:递归从N个进程里选一个满足条件的进程作为一个安全序列的第一个元素,之后再各自从剩下的进程中选择满足条件的作为第二个元素…… 问题:由于确定每一个安全序列、以及确定安全序列的每一个元素的过程中Finish[i...

    银行家算法——输出所有安全序列

    银行家算法的具体思路可见我的另一篇文章 点击了解

    思路:递归从N个进程里选一个满足条件的进程作为一个安全序列的第一个元素,之后再各自从剩下的进程中选择满足条件的作为第二个元素……

    问题:由于确定每一个安全序列、以及确定安全序列的每一个元素的过程中Finish[i]和Work[j]都在变化,所以需要一个撤回操作的步骤(回溯)

    和深度优先搜索类似

    代码如下

    #include<string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #define max 10
    int PN;           //进程数
    int RT;           //资源数
    int Resourse[max];//资源种类
    int Available[max];//系统剩余资源
    int Work[max]; //工作向量
    int Allocation[max][max];//进程已分配资源
    int Need[max][max];//进程目前资源需求
    int MAX[max][max];//进程最大资源需求
    int Request[max];//申请
    bool Finish[max];//完成标志
    int sum;//安全序列计数
    int choice;//选择申请资源
    typedef struct
    {
    	int SafeOrder[max];
    	int top;
    }stack;
    void push(stack *s, int x)
    {
    	s->SafeOrder[s->top] = x;
    	s->top++;
    }
    void pop(stack *s)
    {
    	s->top--;
    }
    stack Order;
    void printOrder()
    {
    	int i;
    	sum++;
    	if (sum == 1) printf("当前系统安全!\n");
    	printf("第%d个安全序列: ", sum);
    	for (i = 0; i < PN; i++)
    	{
    		if (i == 0)
    			printf("P%d", Order.SafeOrder[i]);
    		else
    			printf("->P%d", Order.SafeOrder[i]);
    	}
    	printf("\n");
    }
    void IsSafe(int k)
    {
    	int i, j;
    	if (k == PN)  //找到了一种安全性序列,打印输出
    	{
    		printOrder();
    		return;
    	}
    	for (i = 0; i<PN; i++)
    	{
    		if (!Finish[i])
    		{
    			bool flag = true;
    			for (j = 0; j<RT; j++)
    				if (Need[i][j] > Work[j])
    					flag = false;
    			if (flag)//暂时放入安全性队列
    			{
    				for (j = 0; j < RT; j++)
    					Work[j] += Allocation[i][j];
    				Finish[i] = true;
    				push(&Order, i + 1);//满足要求的进程放进安全序列
    				IsSafe(k + 1);     //搜索下一个
    				pop(&Order);       //回溯,将第i个进程所做的改变恢复,也就是弹出刚刚放进去的进程
    				for (j = 0; j<RT; j++)
    					Work[j] -= Allocation[i][j];
    				Finish[i] = false;
    			}
    		}
    	}
    }
    void Input(int a, int b, int c[max][max])
    {
    	int i, j;
    	for (i = 0; i < b; i++)
    		if (i == 0) printf("    R%d ", i + 1);
    		else printf("R%d ", i + 1);
    		printf("\n");
    		for (i = 0; i < a; i++)
    		{
    			printf("P%d  ", i + 1);
    			for (j = 0; j < b; j++)
    				scanf("%d", &c[i][j]);
    		}
    }
    void init()
    {
    	int i, j;
    	sum = 0;
    	Order.top = 0;
    	printf("初始化: 请输入进程个数和资源总类: ");
    	scanf("%d%d", &PN, &RT);
    	printf("请输入各类资源数量: \n");
    	for (i = 0; i < RT; i++)
    		printf("R%d ", i + 1);
    	printf("\n");
    	for (i = 0; i < RT; i++)
    		scanf("%d", &Resourse[i]);
    	printf("请输入每个进程对每种资源的最大需求量:\n");
    	Input(PN, RT, MAX);
    	printf("请输入各类资源已分配量:\n");
    	Input(PN, RT, Allocation);
    	for (i = 0; i < PN; i++)
    		for (j = 0; j < RT; j++)
    			Need[i][j] = MAX[i][j] - Allocation[i][j];
    	for (i = 0; i < RT; i++)
    	{
    		int s[max] = { 0 };
    		for (j = 0; j < PN; j++)
    			s[i] += Allocation[j][i];
    		Available[i] = Resourse[i] - s[i];
    		Work[i] = Available[i];
    	}
    	for (j = 0; j < PN; j++)
    		Finish[i] = false;
    }
    bool  Apply()//进程资源申请
    {
    	int i;
    	printf("选择申请资源的进程: P");
    	scanf("%d", &choice);
    	printf("输入各类资源申请数量\n");
    	for (i = 0; i < RT; i++)
    		printf("R%d ", i + 1);
    	printf("\n");
    	for (i = 0; i < RT; i++)
    		scanf("%d", &Request[i]);
    	for (i = 0; i < RT; i++)
    		if (Request[i] <= Need[choice - 1][i])
    		{
    			if (Request[i] > Available[i])
    			{
    				printf("资源不足!"); return false;
    			}
    
    		}
    		else//申请超出所需
    		{
    			printf("申请超出所需!"); return false;
    		}
    	return true;
    }
    bool banker()
    {
    	sum = 0;
    	Order.top = 0;
    	int i = choice - 1, j;
    	for (j = 0; j < RT; j++)//试分配
    	{
    		Available[j] -= Request[j];
    		Allocation[i][j] += Request[j];
    		Need[i][j] -= Request[j];
    		Work[j] = Available[j];
    	}
    	for (j = 0; j < PN; j++)
    		Finish[j] = false;
    	IsSafe(0);
    	if (sum == 0)
    	{
    		for (j = 0; j < RT; j++)
    		{
    			Available[j] += Request[j];
    			Allocation[i][j] -= Request[j];
    			Need[i][j] += Request[j];
    			Work[j] = Available[j];
    		}
    		return false;
    	}
    	return true;
    }
    void print()
    {
    	int i, j;
    	printf("\n资源已分配|资源尚需: \n");
    	for (i = 0; i < RT; i++)
    		if (i == 0) printf("           R%d    ", i + 1);
    		else printf("R%d    ", i + 1);
    		printf("\n");
    		for (i = 0; i < PN; i++)
    		{
    			printf("   P%d   :", i + 1);
    			for (j = 0; j < RT; j++)
    				printf("%2d|%-2d ", Allocation[i][j], Need[i][j]);
    			printf("\n");
    		}
    		printf("系统剩余:");
    		for (i = 0; i < RT; i++)
    			printf("  %-4d", Available[i]);
    		printf("\n");
    }
    void Menu()
    {
    	printf("------------------Banker-----------------------\n");
    	printf("*              1.初始化数据                    *\n");
    	printf("*              2.检验T0时刻安全性              *\n");
    	printf("*              3.资源申请                      *\n");
    	printf("*              4.退出                          *\n");
    	printf("------------------------------------------------\n");
    }
    void  main()
    {
    	bool flag1, flag2;
    	Menu();
    Initialization:init();
    	IsSafe(0);
    	if (sum == 0)
    	{
    		printf("当前系统处于不安全状态,请重新初始化!\n");
    		goto Initialization;
    
    	}
    	else print();
    Application: flag1 = Apply();
    	if (flag1)
    	{
    		flag2 = banker();
    		if (!flag2)
    		{
    			printf("资源申请造成系统处不安全状态!申请失败!请重新申请\n");
    			goto Application;
    		}
    		else
    		{
    			printf("申请成功!");
    			print();
    		}
    	}
    	else
    	{
    		printf("申请失败!请重新申请\n");
    		goto Application;
    	}
    	int n;
    	printf("是否还有进程申请资源? 是请输入1,否请输入0 :");
    	scanf("%d", &n);
    	if (n == 1)
    		goto Application;
    }
    
    
    展开全文
  • 用Spring的RestTemplate 把一个List的集合用JSON的形式,送信 在接收端的代码 查出 不安全的反序列化 请问是什么原因?
  • python序列化反序列化Before I go on rambling about what insecure deserialization is, I will ... 在继续探讨什么是不安全的反序列化之前,我将解释什么是序列化和反序列化。 Serialization is the process...

    python序列化反序列化

    Before I go on rambling about what insecure deserialization is, I will explain what serialization and deserialization is.

    在继续探讨什么是不安全的反序列化之前,我将解释什么是序列化和反序列化。

    Serialization is the process of converting an object into a stream of bytes to store the object to memory, a database, or a file. Do not confuse object with variable. Think of it like this — variable can store only one data type at a time whereas an object can store multiple. Serialization goes by different names in different languages, it is serialization for java, pickling for python and marshalling for Perl and some other languages. Deserialization is the process of converting serialized data in bytes to readable format.

    序列化是将对象转换为字节流以将对象存储到内存,数据库或文件的过程。 不要将对象与变量混淆。 可以这样想-变量一次只能存储一种数据类型,而一个对象可以存储多种数据类型。 序列化在不同的语言中使用不同的名称,它是用于Java的序列化 ,用于python的腌制以及用于Perl和其他语言的编组反序列化是将字节序列化的数据转换为可读格式的过程。

    Allow me to demonstrate.

    请允许我示范。

    We will be using a library called pickle in python. If you have a terminal up and running, type the following commands.

    我们将在python中使用一个名为pickle的库。 如果您的终端已启动并正在运行,请键入以下命令。

    python3 

    This will open a Python3 interactive session in the terminal. Now import the pickle library.

    这将在终端中打开Python3交互式会话。 现在导入泡菜库。

    >>>import pickle

    Next, define an object.

    接下来,定义一个对象。

    >>>example = { "name" : "Shibin" , "position" : "sec engineer" }

    Now that we have defined our object we will pickle (serialize) it. There are a lot of functions in the pickle library whose documentation can be found here. But here, we will be using only two functions from that library — dumps() and loads().

    现在我们已经定义了对象,我们将其腌制(序列化)。 在pickle库中有很多函数,其文档可以在这里找到。 但是在这里,我们将仅使用该库中的两个函数-dumps()load()

    pickle.dumps() is used to pickle (serialize) the data and it takes a variable, function or class to be pickled as its argument.

    pickle.dumps()用于对数据进行腌制(序列化),并且需要将要腌制的变量,函数或类作为其参数。

    pickle.loads() is used to unpickle (deserialize) the data and takes a variable containing byte stream as a valid arguement.

    pickle.loads()用于解开数据(反序列化),并使用包含字节流的变量作为有效参数。

    Let’s pickle the object that we have.

    让我们腌制我们拥有的对象。

    >>>pickle.dumps(example)

    This will pickle the data and the output will look somewhat like this:

    这将使数据腌制,并且输出将如下所示:

    b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x06\x00\x00\x00Shibinq\x02X\x08\x00\x00\x00positionq\x03X\x0c\x00\x00\x00sec engineerq\x04u.'

    Now to use loads(),

    现在使用loads(),

    >>>pickle.loads(b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x06\x00\x00\x00Shibinq\x02X\x08\x00\x00\x00positionq\x03X\x0c\x00\x00\x00sec engineerq\x04u.')

    which will give us the data back.

    这将给我们返回数据。

    {'name': 'Shibin', 'position': 'sec engineer'}

    Now you might be wondering how this can potentially be a threat to be listed in OWASP Top 10 vulnerabilities. Insecure deserialization is when an app deserializes the data that it gets without any kind of validation, or even the authenticity of the data.

    现在您可能想知道如何将其潜在地威胁到OWASP十大漏洞中 。 不安全的反序列化是指应用程序对获得的数据进行反序列化而无需任何种类的验证,甚至没有数据的真实性。

    Again, allow me to demonstrate.

    再次,请允许我演示。

    Consider that there is a (shady) Python app which has both server side(server.py) and client side(client.py). The client will pickle some data and send it over to the server and the server will unpickle the data and display it.

    考虑有一个(幕后)Python应用程序,它同时具有服务器端(server.py)和客户端(client.py)。 客户端将对某些数据进行腌制并将其发送到服务器,服务器将解开数据并将其显示。

    The script for client.py is:

    client.py的脚本是:

    import osimport pickle
    def serialize_exploit(): name = {"name":"shibin","pos":"sec Engineer"} f = open("demo.pickle","wb") safecode = pickle.dump(name,f) return safecode
    if __name__ == '__main__': safecode = serialize_exploit()

    (Hmm. Shady app indeed, why does it import the os library!?!?!) The script has a function serialize_exploit() which defines an object called name. Then a file called demo.pickle is opened for writing in binary format after which dump() (not dumps()) is used to pickle the object name and write into the file.

    (嗯,确实是Shady应用程序,为什么它要导入os库!?!?!)。该脚本具有一个函数serialize_exploit() ,该函数定义了一个名为name的对象 然后,打开一个名为demo.pickle的文件以二进制格式写入,然后使用dump() (而不是dumps())来腌制对象名称并写入文件。

    Run the client with python3.

    使用python3运行客户端。

    python3 client.py

    The pickled data is written into the file demo.pickle. Printing the file using cat will show:

    腌制后的数据被写入文件demo.pickle。 使用cat打印文件将显示:

    ?}q(XnameqXshibinqXposqX                        sec Engineerqu.%

    The script for server.py is:

    server.py的脚本是:

    import osimport pickle
    def insecure_deserialization(): f = open("demo.pickle","rb") na = pickle.load(f) return na
    if __name__ == '__main__': print(insecure_deserialization())

    This script has a function called insecure_deserialization() which opens the file demo.pickle to read the data in binary format. The function load() (not loads()) will read the data and unpickle. This data is then printed.

    该脚本具有一个称为insecure_deserialization()的函数,该函数打开文件demo.pickle来读取二进制格式的数据。 函数load() (不是load())将读取数据并进行修补。 然后打印该数据。

    Run the server with python3.

    使用python3运行服务器。

    python3 server.py

    I will print the data

    我将打印数据

    {"name":"shibin","pos":"sec Engineer"}

    So in short, the client will pickle (serialise) some data and the server, without even validating the data it got, unpickles (deserializes) the data.

    简而言之,客户端将对某些数据进行腌制(序列化),而服务器甚至不验证所获取的数据,就对它们进行腌制(反序列化)。

    Now begins the interesting part.

    现在开始有趣的部分。

    Let us focus on client.py. Since there is no validation whatsoever, it will pickle any data thrown at it. So lets try to modify the script client.py as shown below

    让我们专注于client.py。 由于没有任何验证,它将使所有抛出的数据腌制。 因此,让我们尝试修改脚本client.py 如下所示

    import osimport pickleclass ImVulnerable():      def __reduce__(self):            return(os.system,('whoami',))def serialize_exploit():      name = {"name":"shibin","pos":"sec Engineer"}      f = open("demo.pickle","wb")      safecode = pickle.dump(ImVulnerable(),f)      return safecodeif __name__ == '__main__':      safecode = serialize_exploit()

    The changes are highlighted in bold. We define a class ImVulnerable() and inside it is a function which returns a linux kernel command using the os library of python. This class is then passed as an argument to dump() which then, as you are familiar by now, pickles it and writes it into the file demo.pickle. The content in the file demo.pickle is now:

    更改以粗体突出显示。 我们定义了一个ImVulnerable()类,它的内部是一个使用python的os返回linux内核命令函数 。 然后,将该类作为参数传递给dump() ,然后,如您现在所熟悉的,将其腌制并将其写入文件demo.pickle。 文件demo.pickle中的内容现在是:

    ?cossystemqXwhoamiq?qRq.%

    Note that we have not edited the file server.py till now. Now when I try to run the server file, it will read the demo.pickle file and then unpickles the data. This will reveal the linux kernel command instead of a text to print. The command ‘whoami’ is executed in the server script!!!!!!!

    请注意,到目前为止,我们尚未编辑文件server.py。 现在,当我尝试运行服务器文件时,它将读取demo.pickle文件,然后释放数据。 这将显示linux内核命令,而不是要打印的文本。 在服务器脚本中执行命令“ whoami”

    If this was really a server and a client,

    如果这确实是服务器和客户端,

    就像执行远程代码执行一样!!!!!! (REMOTE CODE EXECUTION, JUST LIKE THAT!!!!!!!!!!!!)

    如何防止这种情况: (How to prevent this:)

    1. DO NOT accept serialized data from untrusted sources.

      不要接受来自不受信任来源的序列化数据。
    2. Run deserialization code with limited access permission.

      使用有限的访问权限运行反序列化代码。
    3. Validate user input. Cyber Security 101 — Never trust user input!

      验证用户输入。 网络安全101-永远不要相信用户输入!

    Hope this article was straightforward. :)

    希望本文简单明了。 :)

    Reference:

    参考:

    翻译自: https://medium.com/@shibinbshaji007/using-pythons-pickling-to-explain-insecure-deserialization-5837d2328466

    python序列化反序列化

    展开全文
  • 银行家算法(安全序列

    万次阅读 2019-11-16 17:48:22
    1)安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。 2)不安全状态:不存在一个安全序列。不安全状态不一定导致死锁。 那么什么是安全序列呢?...
  • 进行代码检查时,Coverity工具在进行json转换时,报Unsafe Deserialization错误,字面意思是不安全的反序列化,根本原因就是反序列化会有漏洞导致的。 看完下文反序列化漏洞的原理后,我们就知道该如何解决这个问题...
  • 如何识别不安全的反序列化1.1. PHP序列化格式1.2 Java序列化格式2. 操作序列化对象2.1. 修改对象属性介绍实验2.2. 修改数据类型介绍实验3. 利用网站程序功能4. 魔术方法5. 注入任意对象介绍实验6. Gadget chains7. ...
  • 当且仅当序列值等于1时,每个用户才会周期性地读取分配的协议序列的0和1,并在一个时隙中发送数据包。它不需要用户之间的时间同步。 我们将延迟性能与ALOHA类型的随机访问方案进行了比较,结果表明,实际上可以通过...
  • Go非常快,非常不安全序列
  • 我还喜欢以一种类型安全的方式直接从我的对象/到我的对象序列化值; 就像JsonUtility一样,但是使用了更友好的CSV(并且没有嵌套对象)。 此类适用于C#对象上的公共字段,并且绝对适用于string , int , float ...
  • 单例模式可以说是最简单的设计模式了,但在使用时也有一些问题需要注意,比如线程安全性和序列化破坏。本文以几个问题为出发点,分析延迟加载、线程安全以及序列化三个方面,深入了解一下单例模式的各种姿势,以便在...
  • 解决这种不安全序列化Json漏洞有什么思路吗?
  • 基于免疫的时间序列预测方法及其在网络安全中的应用
  • A8 不安全的反序列

    2020-02-11 18:07:05
    对反序列化的利用是有点困难,因为在不更改或调整底层可被利用代码的情况下,现成的反序列化漏洞很难被使用。 这一问题包括在TOP10的行业调查中,而不是基于可量化的数据。 有些工具可以被用于发现反序列化缺陷,...
  • 银行家算法 安全序列

    2010-12-05 16:13:10
    进程可动态地申请资源和释放资源,系统按进程的申请动态地分配资源,要求程序具有显示和打印各进程的某一个时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据...
  • 序列密码体制是确实是理论上最安全的密码体制,因为Shannon证明了一次一密密码体制是绝对安全的,每个字节明文都对应这一个字节的密钥,而序列密码的设计就是基于此而设计。 序列密码 明文、密文、密钥以位(或者...
  • 序列化与反序列化什么是不安全的反序列化?不安全的反序列化漏洞如何产生?不安全的反序列化有何影响?如何利用不安全的反序列化漏洞如何识别不安全的反序列化PHP序列化格式Java序列化格式操作序列化对象修改对象...
  • 基于可靠度理论和风险...兼顾电网安全运行水平和系统覆冰发展趋势,综合覆冰风险指标和系统覆冰度指标构建融冰决策指标,提出融冰序列决策方案的制定方法。IEEE 30节点系统仿真结果验证了所提方法的合理性与可行性。
  • Android中的序列化反序列化不匹配导致的漏洞解析 本文仅供安全技术交流,请勿用于不正当的用途,造成的一切后果与本文作者无关. 0x00 前言 上一次提到了这个漏洞,其中提到了修补方案,就是去验证intent指向的app和appB...
  • 类型安全的功能序列,用于处理TypeScript和JavaScript中的可迭代数据。 ★★★喜欢这个项目吗? ,或以支持我的工作! 谢谢。 ★★★ 关于顺序 Sequency是一种轻量级(最小5 KB ),经过严格测试( 200多次测试,99...
  • Kryo对象线程不安全,但是能加快序列化和反序列的速度* public final class KryoSerializeUtil { /**Kryo对象线程不安全,但是能加快序列化和反序列的速度*/ static private final ThreadLocal<Kryo> tLocal...
  • 银行家算法是一种避免死锁,为不同进程分配资源的,保证不同进程都能分配到资源,最终求出实现资源分配后不同进程运行的序列,此序列称为安全序列, 具体的原理和解释就看书吧~ 我这里将书中的例子写成代码,时间...
  • --仿照序列表 drop table if exists sequence; create table sequence ( seq_name VARCHAR(50) NOT NULL, current_val INT NOT NULL, increment_val INT NOT NULL DEF...
  • 序列化单例和类型安全的枚举在序列化和反序列时,如果目标对象是唯一的,那么必须加倍小心,这通常会在实现单例和类型安全的枚举时发生。 如果你使用Java 语言的enum结构,那么你就不必担心序列化,它能够正常工作...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,015
精华内容 3,606
关键字:

安全序列的