避免死锁的银行家算法
死锁的定义>
如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那仫该组进程就是死锁的.
产生死锁的必要条件>
1).互斥条件:进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求资源只能等待,直至占有该资源的进程用毕释放.
2).请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已经被其他进程占有,此时请求进程被保持,但对自己所获得的资源又保持不放.
3).不可抢占条件:进程已获得的资源在未使用完之前不可被抢占,只能在使用完成后自己释放.
4).环路等待:在发生死锁时,必然存在一个进程,资源的循环链.
死锁产生的原因>
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说明系统处于安全状态,否则系统处于不安全状态.
在实现这份代码的时候陷入了一个误区那就是当你找到了一个安全序列之后,它查找过的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])
- {
- //选择一个Finish[i]=false,Need[i]<=Work[i]
- 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)
- {
- //如果试分配成功则更新Available,Allocation,Allocation的状态
- 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
- {
- //只要试分配失败则将Finish置为false
- 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;
- //分配成功将Finish的值置为false
- 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;
- //分配成功将Finish的值置为false
- 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;
- }
- }
- }
虽然搞了一下午写完整了这个银行家算法,整体效果还算满意,但是作为网络工程专业的学生今年虽然学了java的GUI但是仍然不会用图形用户界面(GUI)来对这个程序做一个界面出来,感觉好悲催,以后一定努力学习这方面的知识
实现效果
- import java.util.Scanner;
- public class Bankers{
- private int need[][],allocate[][],max[][],avail[][],np,nr;
- private void input(){
- Scanner sc=new Scanner(System.in);
- System.out.print("Enter no. of processes and resources : ");
- np=sc.nextInt(); //no. of process
- nr=sc.nextInt(); //no. of resources
- need=new int[np][nr]; //initializing arrays
- max=new int[np][nr];
- allocate=new int[np][nr];
- avail=new int[1][nr];
- System.out.println("Enter allocation matrix -->");
- for(int i=0;i<np;i++)
- for(int j=0;j<nr;j++)
- allocate[i][j]=sc.nextInt(); //allocation matrix
- System.out.println("Enter max matrix -->");
- for(int i=0;i<np;i++)
- for(int j=0;j<nr;j++)
- max[i][j]=sc.nextInt(); //max matrix
- System.out.println("Enter available matrix -->");
- for(int j=0;j<nr;j++)
- avail[0][j]=sc.nextInt(); //available matrix
- sc.close();
- }
- private int[][] calc_need(){
- for(int i=0;i<np;i++)
- for(int j=0;j<nr;j++) //calculating need matrix
- need[i][j]=max[i][j]-allocate[i][j];
- return need;
- }
- private boolean check(int i){
- //checking if all resources for ith process can be allocated
- for(int j=0;j<nr;j++)
- if(avail[0][j]<need[i][j])
- return false;
- return true;
- }
- public void isSafe(){
- input();
- calc_need();
- boolean done[]=new boolean[np];
- int j=0;
- while(j<np){ //until all process allocated
- boolean allocated=false;
- for(int i=0;i<np;i++)
- if(!done[i] && check(i)){ //trying to allocate
- for(int k=0;k<nr;k++)
- avail[0][k]=avail[0][k]-need[i][k]+max[i][k];
- System.out.println("Allocated process : "+i);
- allocated=done[i]=true;
- j++;
- }
- if(!allocated) break; //if no allocation
- }
- if(j==np) //if all processes are allocated
- System.out.println("\nSafely allocated");
- else
- System.out.println("All proceess cant be allocated safely");
- }
- public static void main(String[] args) {
- new Bankers().isSafe();
- }
- }
- --------------------------------------------------------------------------------------------------------------------------
- Output
- --------------------------------------------------------------------------------------------------------------------------
- Enter no. of processes and resources : 3 4
- Enter allocation matrix -->
- 1 2 2 1
- 1 0 3 3
- 1 2 1 0
- Enter max matrix -->
- 3 3 2 2
- 1 1 3 4
- 1 3 5 0
- Enter available matrix -->
- 3 1 1 2
- Allocated process : 0
- Allocated process : 1
- Allocated process : 2
- Safely allocated