操作系统——银行家算法

首先了解一波产生死锁的必要条件
    1).互斥条件:进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求资源只能等待,直至占有该资源的进程用毕释放.
    2).请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已经被其他进程占有,此时请求进程被保持,但对自己所获得的资源又保持不放.
    3).不可抢占条件:进程已获得的资源在未使用完之前不可被抢占,只能在使用完成后自己释放.
    4).环路等待:在发生死锁时,必然存在一个进程,资源的循环链.

银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。

安全序列是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。(即在分配过程中,不会出现某一进程后续需要的资源量比其他所有进程及当前剩余资源量总和还大的情况)
注:存在安全序列则系统是安全的,如果不存在则系统不安全,但不安全状态不一定引起死锁。

原理过程:
系统给当前进程分配资源时,先检查是否安全:在满足当前的进程X资源申请后,是否还能有足够的资源去满足下一个距最大资源需求最近的进程(如某进程最大需要5个单位资源,已拥有1个,还尚需4个),若可以满足,则继续检查下一个距最大资源需求最近的进程,若均能满足所有进程,则表示为安全,可以允许给当前进程X分配其所需的资源申请,否则让该进程X进入等待。

(注:检查过程中,每拟满足一个进程,则进行下个检查时,当前可用资源为回收上一个进程资源的总值,每满足一个进程表示此进程已结束,资源可回收。)

算法过程:

1).银行家算法中的数据结构

      (1).可利用资源向量

      (2).最大需求矩阵

      (3).分配矩阵

      (4).需求矩阵

2)对于当前需要申请资源的进程Pi X
(1) 检查if( Request[ i ][ j ]<=Need[ i ][ j ] ) goto (2)
else error(“进程 i 对资源的申请量大于其说明的最大值 ”);
(2) 检查 if ( Request[ i ][ j ]<=Available[ j ] ) goto (3)
else wait() ; /*注意是等待!即在对后续进程的需求资源判断中,若出现不符合的则安全检查结束,当前进程进入等待*/
(3) 系统试探地把资源分给Pi 并修改各项属性值 (具体是否成立,则根据安全检查的结果)
Available[ j ]  =Available[ j ] — Request[ i ][ j ]
Allocation[ i ][ j ]=Allocation[ i ][ j ] +Request[ i ][ j ]

Need[ i ][ j ]=Need[ i ][ j ]— Request[ i ][ j ]


具体的算法实现:

#include <iostream>
#include <string.h>
#include <string>
using namespace std;
const int maxnsource = 100;

const int maxnprocess = 50;

int available[maxnsource];//可以使用的资源。
int max[maxnprocess][maxnprocess];//最大需求矩阵。
int allocation[maxnprocess][maxnprocess];//已经分配的矩阵。
int need[maxnprocess][maxnprocess];//还需要的矩阵。
int requestsource[maxnprocess][maxnprocess];//进程请求的矩阵。
int finish[maxnprocess];//进程是否能得到足够的资源使其结束。
int n, m;
int i, j;
int p[maxnsource];//记录进程号

int safe()//判断是否为安全的
{
int cnt = 0;
int flag = 0;
int temp[maxnsource];
for (i = 0; i < n; i++)
temp[i] = available[i];
for (i = 0; i < m; i++)
{
if (finish[i] == 0)
{
for (j = 0; j < n; j++)
{
if (need[i][j] > temp[j])
break;
}
if (j == n)
{
finish[i] = 1;
for (int k = 0; k < n; k++)
temp[k] += allocation[i][k];
p[cnt++] = i;
i = -1;//这里不是0,重置之后i++会变为1,就错了。
}
else
continue;
if (cnt == m)
{
cout << "系统是安全的" << endl;
cout << "安全序列:" << endl;
for (i = 0; i<cnt; i++)  
{
cout << p[i];
if (i != cnt - 1)
{
cout << "-->";
}
}
cout << "" << endl;
return 1;
}
}
}
cout << "系统是不安全的" << endl;
return 0;
}


void bank()//银行家算法
{
int cur;
while (1)
{
cout << "输入要申请资源的进程号" << endl;
cin >> cur;
cout<< "输入进程所请求的各资源的数量" << endl;
for (int i = 0; i < n; i++)
cin >> requestsource[cur][i];
for (int i = 0; i < n; i++)
{
if (requestsource[cur][i] > need[cur][i])
{
cout << "输入的请求数超过进程的需求量!请重新输入!" << endl;
continue;
}
if (requestsource[cur][i] > available[i])
{
cout << "输入的请求数超过系统有的资源数!请重新输入!" << endl;
continue;
}
}
for (int i = 0; i < n; i++)
{
available[i] -= requestsource[cur][i];
allocation[cur][i] += requestsource[cur][i];
need[cur][i] -= requestsource[cur][i];
}
for (int i = 0; i < m; i++)
finish[i] = 0;
if (safe())
{
cout << "同意分配请求!" << endl;
}
else
{
cout << "您的请求被拒绝!" << endl;
for (int i = 0; i < n; i++)
{
available[i] += requestsource[cur][i];
allocation[cur][i] -= requestsource[cur][i];
need[cur][i] += requestsource[cur][i];
}
for (int i = 0; i < m; i++)
finish[i] = 0;
string s;
cout << "是否还想再次请求分配吗?如果想,请输入YES" << endl;
cin >> s;
if (s == "YES")
continue;
else
break;
}
}
}


int main()
{
memset(finish, 0, sizeof(finish));
cout << "输入进程的数量:";
cin >> m;
cout << "输入资源的种类:";
cin >> n;
cout << "输入每个进程最多所需要的资源数:";
for (i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> max[i][j];
cout << "输入每个进程已经分配的资源数:";
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
cin >> allocation[i][j];
need[i][j] = max[i][j] - allocation[i][j];
if (need[i][j] < 0)
{
cout << "输入的第" << i + 1 << "个进程所拥有的第" << j + 1 << "个资源数 错误,请重新输入:" << endl;
j--;
continue;
}
}
}
cout << "输入各资源现有的资源数:";
for (i = 0; i < n; i++)
cin >> available[i];
/*for (i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cout << max[i][j] << " ";
cout << endl;
}
for (i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cout << allocation[i][j] << " ";
cout << endl;
}
for (i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cout << need[i][j] << " ";
cout << endl;
}*/
safe();
bank();
return 0;
}

猜你喜欢

转载自blog.csdn.net/abandoninged/article/details/80638300