進程的併發和死鎖——銀行家算法

源代碼下載:https://download.csdn.net/download/xust_kevin/10748248

進程的併發和死鎖之銀行家算法,Dijkstra把系統比作一個銀行家,它佔有有限資源。通過銀行家算法來給資源請求的進程分配資源,以避免資源佔用發生死鎖。

考慮一個具有n個進程和m種不同類型資源的系統,每一個進程對系統發出資源請求,系統根據當前的資源分配情況和可利用資源量來動態分配資源。

變量說明:

Allocate:資源分配矩陣

表示系統當前已經分配給各個進程 的資源數量

Available:可利用資源矩陣

表示系統當前可以用來分配的剩餘資源

Claim:最大需求矩陣

表示每一個進程對每種資源所需要的最大數量

Resuorce:系統資源矩陣

表示系統總共擁有的每種資源數量

Need:資源需求矩陣

表示每個進程當前所需要得到的每種資源數量

基本思想:

在每一個進程請求系統分配資源時,根據銀行家算法的原理判斷請求的資源是否可合理以及分配資源後的進程是否安全來進行判斷,如果滿足以上兩個條件則分配當前進程請求的資源數量,否則拒絕分配資源。

關鍵點:

  1. 判斷請求資源是否大於可利用資源
  2. 判斷請求資源是否大於最大需求資源
  3. 判斷分配資源後進程是否安全
  4. 系統狀態的回滾(初態和末態的選擇,回滾即爲拒絕分配資源)

實現步驟:

1.判斷請求資源是否大於可利用資源

通過函數傳參的方式將當前進程號和請求的資源傳入函數中

用系統資源矩陣減去資源分配矩陣(需要做統一維度處理,即每一列相加得到每一種資源已分配的數量)得到可利用資源矩陣,判斷請求資源是否大於對應的可以利用資源,否則拒絕資源請求

代碼如下:

int temp ;
for (i = 0; i < M; i++)
{
    temp = 0;
    for (j = 0; j < N; j++)
    temp+= Allocate[j][i];
    Avaliable[i] = Resource[i] - temp;
}
			

//拷貝可利用資源
for (i = 0; i < M; i++)
    Avaliable_copy[i] = Avaliable[i];

//判斷請求資源是否超過可利用的資源
bool flag_request = true;
for (int count = 0; count < M; count++)
{
	if (Avaliable[count] - Request[count] >= 0)
		Avaliable_copy[count] = Avaliable[count] - Request[count];
        else
	    {
		flag_request = false;
		break;
	    }
}

 

 

2.判斷請求資源是否大於最大需求資源

在當前可利用資源可以進行資源分配的情況下,對請求資源的進程分配相應的資源數量,對進行分配後的資源分配矩陣進行檢查,判斷資源分配矩陣是否存在分配資源大於最大需求資源的情況,如果分配資源矩陣中的當前進程的分配資源都沒有大於其所需要的最大需求資源則分配資源,否則拒絕資源請求

代碼如下:

for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
    {
        Allocate_copy[i][j] = Allocate[i][j];//拷貝分配矩陣
        Need_copy[i][j] = Need[i][j];//拷貝需求矩陣
    }
				
for (i = 0; i < M; i++)
    Allocate_copy[pro_number - 1][i] += Request[i];//分配請求資源

for (i = 0; i < M; i++)//判斷請求資源是否大於最大所需資源
    if (Allocate_copy[pro_number - 1][i] > Claim[pro_number - 1][i])
	{
	    flag_need = false;
	    break;
	}

3.判斷分配資源後進程是否安全

當前兩個條件都滿足的情況下,判斷分配資源給當前進程後,系統剩下的可利用資源是否可以滿足分配給任意一個未達到最大資源需求的進程(剩餘資源能夠分配個某個進程,使得這個進程達到最大資源需求量,以運行完這個進程,釋放出更多的資源)

代碼如下:

for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
        Need_copy[i][j] = Claim[i][j] - Allocate_copy[i][j];//重新分配資源後的需求矩陣

//判斷分配資源後,可利用資源能否滿足結束任意一個進程
bool flag_process[N] = { true,true,true,true };
for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
        if (Need_copy[i][j] > Avaliable_copy[j])
            flag_process[i] = false;
					

 

4.系統狀態的回滾

因爲在判斷不滿足分配資源條件後應該拒絕資源請求,所以應該將所有相關的資源恢復到之前的狀態。我在程序中使用copy代替分配的矩陣,如果滿足分配條件就將copy矩陣的值拷貝給原矩陣,否者不作複製操作(保持原來的狀態不變)

 

完整代碼:

下面提供銀行加算法的完整算法,因爲時間倉促,寫的比較亂,沒有將沒個方法單獨分開。請讀者根據步驟自行設計。

詳細代碼:

bool Banker(int(&Allocate)[N][M], int(&Request)[M], int pro_number)
{
    int Need[N][M] = { 0 };
    int Need_copy[N][M] = { 0 };
    int Avaliable[M] = { 0 };
    int Avaliable_copy[M] = { 0 };
    int Allocate_copy[N][M] = { 0 };
    //求需求(Need)矩陣
    for (i = 0; i < N; i++)
        for ( j = 0; j < M; j++)
	    Need[i][j] = Claim[i][j] - Allocate[i][j];

    //求可利用資源(Avaliable)矩陣
    int temp ;
    for (i = 0; i < M; i++)
	{
	    temp = 0;
	    for (j = 0; j < N; j++)
	    temp+= Allocate[j][i];
	    Avaliable[i] = Resource[i] - temp;
	}
			

    //拷貝可利用資源
    for (i = 0; i < M; i++)
	Avaliable_copy[i] = Avaliable[i];

    //判斷請求資源是否超過可利用的資源
    bool flag_request = true;
    for (int count = 0; count < M; count++)
	{
	    if (Avaliable[count] - Request[count] >= 0)
	        Avaliable_copy[count] = Avaliable[count] - Request[count];
	    else
	        {
		    flag_request = false;
		    break;
		}
	}

    bool flag_assign = false;
    bool flag_need = true;
    //當可利用資源足夠分配時判斷是否安全
    if (flag_request == true)
	{
	    for (i = 0; i < N; i++)
		for (j = 0; j < M; j++)
                    {
			Allocate_copy[i][j] = Allocate[i][j];//拷貝分配矩陣
			Need_copy[i][j] = Need[i][j];//拷貝需求矩陣
		    }
				
		for (i = 0; i < M; i++)
		    Allocate_copy[pro_number - 1][i] += Request[i];//分配請求資源

		for (i = 0; i < M; i++)//判斷請求資源是否大於最大所需資源
		    if (Allocate_copy[pro_number - 1][i] > Claim[pro_number - 1][i])
			{
			    flag_need = false;
			    break;
			}
					
		if (flag_need == true)
		    {
		        for (i = 0; i < N; i++)
			    for (j = 0; j < M; j++)
	                        Need_copy[i][j] = Claim[i][j] - Allocate_copy[i][j];//重新分配資源後的需求矩陣
			//判斷分配資源後,可利用資源能否滿足結束任意一個進程
			bool flag_process[N] = { true,true,true,true };
			for (i = 0; i < N; i++)
				for (j = 0; j < M; j++)
				        if (Need_copy[i][j] > Avaliable_copy[j])
					    flag_process[i] = false;						
					
			//當分配資源後是進程安全時,執行分配
			int count = 0;
			for (i = 0; i < N; i++)
			    if (flag_process[i] == true)
				count++;

			cout <<"安全進程個數:"<< count << endl<<endl;
			if (count>0)
			    {

			        flag_assign = true;
				for (i = 0; i < N; i++)
				    for (j = 0; j < M; j++)
					{
					    Allocate[i][j] = Allocate_copy[i][j];
					    Need[i][j] = Need_copy[i][j];
					}
				for (i = 0; i < M; i++)
				    Avaliable[i] = Avaliable_copy[i];
				}

				if (flag_assign == true)
				{
					//顯示分配信息
					cout << "Allocate=" << endl;//執行分配後的分配矩陣
					for (i = 0; i < N; i++)
					{
						for (j = 0; j < M; j++)
							cout << Allocate[i][j] << "  ";
						cout << endl;
					}
						
					cout << endl;

					cout << "Need=" << endl;//執行分配後的需求矩陣
					for (i = 0; i < N; i++)
					{
						for (j = 0; j < M; j++)
							cout << Need[i][j] << "  ";
						cout << endl;
					}
						
					cout << endl;

					cout << "Avaliable=" << endl;//執行分配後的可利用矩陣
					for (i = 0; i < M; i++)
						cout << Avaliable[i]<<" ";
					cout << endl;
					release(pro_number);
					return true;
				}
				else
				{
					cout << "執行分配不安全" << endl;
					return false;
				}


			}
			else
			{
				cout << "請求資源超過最大所需資源"<<endl;
					return false;
			}
				

		}
		else
		{
			cout << "請求資源大於可利用資源"<<endl;
			return false;
		}

		
	}

源代碼下載:https://download.csdn.net/download/xust_kevin/10748248

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章