C语言实现死锁的检测与解除(含源代码)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、编程内容

处理进程死锁的方法一般包括:预防死锁,避免死锁,死锁的检测与解除。其中,预防死锁和避免死锁是采用事先预防的策略。预防死锁通过破坏产生死锁的四个必要条件中的一个或几个来实现,而预防死锁主要利用银行家算法来进行事先预防。
如果在系统中,既不采取死锁预防措施,也未配有死锁避免算法,系统很可能就会发生死锁。在这种情况下,系统应当提供两个算法:
(1)死锁检测算法:该方法用于检测系统状态,以确定系统中是否发生了死锁。
(2)死锁解除算法:当认定系统中已发生了死锁,利用该算法将系统从死锁状态中解放出来。
以下模拟程序实现进程死锁的检测与解除。

二、死锁检测

1.数据结构

可利用资源Available,它表示m类资源中每类资源可用数目。
请求矩阵Request ,一个m×n矩阵,用以表示进程当前对各类资源的请求数目。
分配矩阵Allocation,一个m×n矩阵,用以表示某一时刻的资源的分配情况。
工作向量Work,表示系统可提供的各类资源的数目。
进程向量L,记录当前已不占用资源的各进程。

2.算法

把某时刻t的可用资源向量Available赋予Work
把不占用资源的进程向量记入表L。
从进程集合中找到一个Requesti  Work的进程,做如下处理:
1.将其资源分配图化简 Work = Work+ Allocationi
2.将它记入L表中
若不能把所有进程都记入L表,则状态S资源分配图不可完全简化的,该系统状态将发生死锁。

Work = Available;
L ={ Li | Allocationi = 0 ∩ Requesti = 0 } 
for all Li∈ L do
  begin
    for all Requesti ≤ Work do
         begin
          Work = Work + Allocationi;
           Li∪L;
          end
   end
deadlock =  (L={ P1, P2,, Pn });

三、死锁解除

本代码中采用的死锁解除方法是终止所有死锁进程,这是一种最简单的方法,但是代价大,被终止进程的前期工作必须放弃。

四、源码

#include <iostream> 
using namespace std;

#define MAXSIZE_V 10//资源种类的最大值
#define MAXSIZE_P 10//进程数目的最大值 

int main(){
	
 
	cout<<"=====程序开始执行=====\n\n"; 

	//定义数据结构 
	int m,n;//资源的种类、进程的数目 
	int Available[MAXSIZE_V];//可利用资源向量 
	int Allocation[MAXSIZE_P][MAXSIZE_V];//分配矩阵 
	int Request[MAXSIZE_P][MAXSIZE_V];//请求矩阵 
	int Work[MAXSIZE_V];//工作向量
	int L[MAXSIZE_P]={0};//进程向量,初值置为0 


	//获取当前状态

	//读入资源种类数 
	cout<<"请输入资源的种类:";
	cin>>m;

	//读入可用资源数 
	cout<<"请输入系统可提供的各种资源的数量(共"<<m<<"个,用空格隔开):";
	for(int i=0;i<m;i++){
		cin>>Available[i];
	}

	//读入进程数目
	cout<<"请输入进程的数目:";
	cin>>n;

	//进程当前对各类资源的请求数目
	cout<<"\n请输入进程当前对各类资源的请求数目:\n";
	for(int i=0;i<n;i++){
		cout<<"请输入进程P"<<i<<"当前对各类资源的请求数目(共"<<m<<"个,用空格隔开):";
		for(int j=0;j<m;j++){
	    	cin>>Request[i][j];
		}
	}

	//读入进程已分配各种资源的数目
	cout<<"\n请输入进程已分配各种资源的数目:\n";
	for(int i=0;i<n;i++){
		cout<<"请输入进程P"<<i<<"已分配各种资源的数量(共"<<m<<"个,用空格隔开):";
		for(int j=0;j<m;j++){
	 	   cin>>Allocation[i][j];
		}
	}
 
 
	//检测算法

	//Work=Available
	for(int i=0;i<m;i++){
		Work[i]=Available[i];
	}
	//不占用资源的进程计入L中,L对应下标单元置1 
	int count=0;//记录表中置1的个数 
	for(int i=0;i<n;i++){
		int flag=0; 
		for(int j=0;j<m;j++){
			if(Allocation[i][j]!=0||Request[i][j]!=0){
				flag=1;
				break;
			}
		}
		if(flag==0){
			L[i]=1;
			count++; 
		}
	} 
	
	//对所有未进入L中的进程,尝试将其化简
	for(int k=0;k<n-count;k++){//还剩几个进程循环几轮
	    //cout<<"========第"<<k<<"轮========";
		for(int i=0;i<n;i++){
			//cout<<"========="<<L[i] ;
			int flag=0;
			if(L[i]==0){
				for(int j=0;j<m;j++){//测试是否Request<=Work 
					if(Request[i][j]>Work[j]){
						flag=1;
						break;
					}
				}
				if(flag==0){//化简,收回所有边 
					for(int j=0;j<m;j++){
						Work[j]=Work[j]+Allocation[i][j];
			    	}
		 		   L[i]=1;//记入表中 
				}
			} 
    	}
	}

	//判断是否所有进程都被回收
	int flag=0;
	for(int i=0;i<n;i++){	
		if(L[i]==0){
			flag=1;
			break;
		}	
	}

	//输出结果并终止导致死锁的进程 
	if(flag==0){
		cout<<"\n该系统不会发生死锁!"; 
	}else{
		cout<<"\n该系统会发生死锁!即将终止导致死锁的进程以解除死锁!\n";
		//回收资源,终止进程
		for(int i=0;i<n;i++){	
			if(L[i]==0){
				for(int j=0;j<m;j++){ 
					Available[j]=Available[j]+Allocation[i][j];
					Allocation[i][j]=0; 
					Request[i][j]=0;	
				}
				cout<<"进程p"<<i<<"已被终止!\n" ;	
	    	}	
    	}
    	//输出终止后系统状态
    	cout<<"\n=====当前系统状态=====\n"; 
    	cout<<"当前系统可利用资源:(";	
		for(int i=0;i<m-1;i++){
			cout<<Available[i]<<"," ;
			}
		cout<<Available[m-1]<<")";
		cout<<"\n当前存在进程:( ";
		for(int i=0;i<n;i++){	
			if(L[i]==1){
				cout<<"P"<<i<<" ";		
	    	}	
    	}
    	cout<<")\n";
	}	
}	
	

五、运行结果

1.不会发生死锁的情况:

在这里插入图片描述

2.会发生死锁的情况:

在这里插入图片描述

  • 18
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值