死鎖的定義>
如果一組進程中的每一個進程都在等待僅由該組進程中的其他進程才能引發的事件,那仫該組進程就是死鎖的.
產生死鎖的必要條件>
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