提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、编程内容
处理进程死锁的方法一般包括:预防死锁,避免死锁,死锁的检测与解除。其中,预防死锁和避免死锁是采用事先预防的策略。预防死锁通过破坏产生死锁的四个必要条件中的一个或几个来实现,而预防死锁主要利用银行家算法来进行事先预防。
如果在系统中,既不采取死锁预防措施,也未配有死锁避免算法,系统很可能就会发生死锁。在这种情况下,系统应当提供两个算法:
(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";
}
}