死锁的定义>
如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那仫该组进程就是死锁的.
产生死锁的必要条件>
1).互斥条件:进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求资源只能等待,直至占有该资源的进程用毕释放.
2).请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已经被其他进程占有,此时请求进程被保持,但对自己所获得的资源又保持不放.
3).不可抢占条件:进程已获得的资源在未使用完之前不可被抢占,只能在使用完成后自己释放.
4).环路等待:在发生死锁时,必然存在一个进程,资源的循环链.
![](https://img-blog.csdn.net/20161204165752210?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
死锁产生的原因>
1).竞争可重用不可抢占式的资源
2).竞争可消耗资源
3).进程推进顺序不当.
可重用性资源:可供重复使用多次的资源.
不可抢占性资源:一旦系统把某资源分配给该进程后,就不能将它强行收回,只能在进程使用完后自动释放.
可消耗资源:又叫临时性资源,它是在进程运行期间,由进程动态的创建和消耗的.
利用银行家算法解决死锁>
1).银行家算法中的数据结构
(1).可利用资源向量Available
(2).最大需求矩阵Max
(3).分配矩阵Allocation
(4).需求矩阵Need
2).银行家算法
Request请求向量,
(1).如果Request[i] <= Need[i][j]转下步,否则它所需要的资源数已超过它所需要的最大值
(2).如果Request[i] <= Available[i][j]转下步,否则尚无足够资源,进程需等待
(3).系统试分配给进程p,并修改Available,Allocation和Need
Available[j] -= Request[j]
Allocation[i][j] += Request[j]
Need[i][j] -= Request[j]
(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态.若安全,才正式分配;否则恢复原来的分配状态,让该进程等待
3).安全性算法
(1).设置两个向量,工作向量Work,在执行安全性算法开始时 Work=Available;Finish:表示有足够的资源分配给进程,使之运行完成,Finish[i]=false;当有足够资源分配给进程时,再另Finish[i]=false
(2).从进程集合中找到一个满足该条件的进程:
Finish[i]=false
Need[i][j] <= Work[j]
(3).当进程获得资源后,可顺利执行,并修改Work向量和Finsh向量
Work[i] += Allocation[i][j]
Finish[i]=true
(4).如果所有进程的Finish[i]=true说明系统处于安全状态,否则系统处于不安全状态.
![](https://img-blog.csdn.net/20150602093650139?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvczYzNDc3MjIwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20150602093659515?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvczYzNDc3MjIwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20150602093545059?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvczYzNDc3MjIwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在实现这份代码的时候陷入了一个误区那就是当你找到了一个安全序列之后,它查找过的Finish必定会被修改为true,而Finish这个数组又是在全局定义的,所以只要找到一次正确的安全序列这个Finish所找到的位就会被置为true会一直出现找到安全序列的,所以在找到安全序列之后一定要将Finish重新赋初值false,这个问题让我排错了半天,在定义变量的时候最好不要定义为全局的。。。
- const int MAXPROCESS=100;
- const int MAXRESOURCE=100;
-
- int Available[MAXRESOURCE];
- int Max[MAXPROCESS][MAXRESOURCE];
- int Allocation[MAXPROCESS][MAXRESOURCE];
- int Need[MAXPROCESS][MAXRESOURCE];
-
- int Request[MAXRESOURCE];
-
- int Work[MAXRESOURCE];
- bool Finish[MAXPROCESS];
- int SafeSeries[MAXPROCESS];
-
- int n;
- int m;
-
- void Init()
- {
- cout<<"请输入进程总数>";
- cin>>n;
- cout<<"请输入资源种类数>";
- cin>>m;
- int i,j;
- printf("请输入%d类资源的当前可利用资源数目>\n",m);
- for( i = 0; i < m; ++i )
- {
- cin >> Available[i];
- }
- printf("最大需求矩阵(%d*%d输入)>\n",n,m);
- for( i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j )
- {
- cin >> Max[i][j];
- }
- }
- printf("分配矩阵(%d*%d输入)>\n",n,m);
- for( i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j )
- {
- cin >> Allocation[i][j];
- }
- }
- printf("需求矩阵(%d*%d输入)\n",n,m);
- for( i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j )
- {
- cin >> Need[i][j];
- }
- }
- }
-
- bool IsSafe()
- {
- int i=0;
- for (i=0;i<n;++i)
- {
- if(Finish[i] == true)
- continue;
- else
- break;
- }
- if(i == n)
- return true;
- else
- return false;
- }
-
- bool Select(int &tmp,int tmpNeed[][MAXRESOURCE])
- {
-
- int j=0;
- for (int i=0;i<n;++i)
- {
- if(Finish[i])
- continue;
- for (j=0;j<m;++j)
- {
- if(tmpNeed[i][j] > Work[j])
- break;
- }
- if(j == m)
- {
- tmp=i;
- return true;
- }
- }
- return false;
- }
-
- bool Safe(int *tmpAvail,int tmpAlloc[][MAXRESOURCE],int tmpNeed[][MAXRESOURCE])
- {
- for(int i = 0; i < n; ++i)
- {
- Finish[i] = false;
- }
- for (int j = 0; j < m; ++j)
- {
- Work[j] = tmpAvail[j];
- }
- int tmp=0;
- int index = 0;
- while(Select(tmp,tmpNeed))
- {
- Finish[tmp] = true;
- for (int k = 0; k < m; ++k)
- {
- Work[k] += tmpAlloc[tmp][k];
- }
- SafeSeries[index++] = tmp;
- }
- if(IsSafe())
- return true;
- else
- return false;
- }
-
- void Display()
- {
- int i=0;
- int j=0;
- cout<<"当前可利用的资源数目"<<endl;
- for(i = 0; i < m; ++i)
- {
- cout << Available[i]<<" ";
- }
- cout<<endl;
- cout<<"最大需求矩阵"<<endl;
- for(i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j)
- {
- cout<<Max[i][j]<<" ";
- }
- cout<<endl;
- }
- cout<<"分配矩阵"<<endl;
- for( i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j )
- {
- cout<<Allocation[i][j]<<" ";
- }
- cout<<endl;
- }
- cout<<"需求矩阵"<<endl;
- for( i = 0; i < n; ++i )
- {
- for( j = 0; j < m; ++j )
- {
- cout<<Need[i][j]<<" ";
- }
- cout<<endl;
- }
- }
-
- void BankA()
- {
- int i=0;
- int index=0;
- cout<<"请输入请求资源的进程下标>";
- cin>>index;
- assert(index < n && index >= 0);
- cout<<"请输入当前的请求资源>"<<endl;
- for (i=0;i<m;++i)
- {
- cin>>Request[i];
- }
- for (i=0;i<m;++i)
- {
- if(Request[i] <= Need[index][i])
- {
- continue;
- }
- else
- {
- cout<<"第一次试分配失败"<<endl;
- break;
- }
- }
- if(i < 3)
- {
- return ;
- }
- for(i=0;i<m;++i)
- {
- if(Request[i] <= Available[i])
- {
- continue;
- }
- else
- {
- cout<<"第二次试分配失败"<<endl;
- break;
- }
- }
- if(i < 3)
- {
- return ;
- }
-
- int tmpAvail[MAXRESOURCE]={0};
- int tmpAlloc[MAXPROCESS][MAXRESOURCE]={0};
- int tmpNeed[MAXPROCESS][MAXRESOURCE]={0};
- memmove(tmpAvail,Available,sizeof(int)*MAXRESOURCE);
- memmove(tmpAlloc,Allocation,sizeof(int)*MAXPROCESS*MAXRESOURCE);
- memmove(tmpNeed,Need,sizeof(int)*MAXPROCESS*MAXRESOURCE);
- for (int i=0;i<m;++i)
- {
- tmpAvail[i] -= Request[i];
- tmpAlloc[index][i] += Request[i];
- tmpNeed[index][i] -= Request[i];
- }
-
- bool ret=Safe(tmpAvail,tmpAlloc,tmpNeed);
- if(ret == true)
- {
-
- memmove(Available,tmpAvail,sizeof(int)*MAXRESOURCE);
- memmove(Allocation,tmpAlloc,sizeof(int)*MAXPROCESS*MAXRESOURCE);
- memmove(Need,tmpNeed,sizeof(int)*MAXPROCESS*MAXRESOURCE);
- cout<<"进程p"<<index<<"请求资源允许"<<endl;
- }
- else
- {
-
- for(int i = 0; i < n; ++i)
- {
- Finish[i] = false;
- }
- cout<<"第三次试分配失败"<<endl;
- }
- }
-
- void Menu()
- {
- cout<<"*************银行家算法*************"<<endl;
- cout<<"**********1.测试安全性代码**********"<<endl;
- cout<<"**********2.测试银行家算法**********"<<endl;
- cout<<"**********3.初始化******************"<<endl;
- cout<<"**********4.打印矩阵****************"<<endl;
- cout<<"**********0.退出********************"<<endl;
- }
test.cpp
- void testBank()
- {
- int index=0;
- int flag=1;
- while (flag)
- {
- Menu();
- cout<<"请输入您的选择"<<endl;
- cin>>index;
- switch(index)
- {
- case 1:
- Safe(Available,Allocation,Need);
- if(IsSafe())
- {
- cout<<"该时刻是安全的,安全序列为>";
- for (int i = 0; i < n ; ++i)
- {
- printf("p%d->",SafeSeries[i]);
- }
- cout<<"end"<<endl;
-
- for(int i = 0; i < n; ++i)
- {
- Finish[i] = false;
- }
- }
- else
- {
- cout<<"该时刻是不安全的"<<endl;
- }
- break;
- case 2:
- BankA();
- if(IsSafe())
- {
- cout<<"安全序列为>";
- for (int i = 0; i < n ; ++i)
- {
- printf("p%d->",SafeSeries[i]);
- }
- cout<<"end"<<endl;
-
- for(int i = 0; i < n; ++i)
- {
- Finish[i] = false;
- }
- }
- else
- {
- cout<<"进程请求资源不被允许"<<endl;
- }
- break;
- case 3:
- Init();
- break;
- case 4:
- Display();
- break;
- case 0:
- flag=0;
- break;
- default:
- cout<<"您的输入错误,请重新输入"<<endl;
- break;
- }
- }
- }