C语言银行家算法
银行家算法银行家算法算法分析全局变量读取文件函数处理函数安全检查银行家算法银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。gitee地址算法分析通过文件读取输入数组数据,然后根据键盘输入执行分配处理,再执行安全算
银行家算法
银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
算法分析
通过文件读取输入数组数据,然后根据键盘输入执行分配处理,再执行安全算法,若安全算法通过,则分配成功,否则分配失败。
全局变量
// 进程数
#define N 5
// 资源数
#define M 3
// 可利用资源数组
int Available[M];
// 最大资源数组
int Max[N][M];
// 已经分配资源数组
int Allocation[N][M];
// 需求数组
int Need[N][M];
// 是否完成
int Success[N];
读取文件函数
read1_data:从fileName文件中读取m个数字到arr中。
read2_data:从fileName文件中读取n行,每行m个数字到arr中。
/**
* 读取一维数组
*/
void read1_data(char *fileName, int arr[], int m)
{
int i;
FILE *fp = fopen(fileName, "rb");
for (i = 0; i < m; i++)
{
fscanf(fp, "%d", &arr[i]);
}
}
/**
* 读取二维数组
*/
void read2_data(char *fileName, int arr[][M], int n, int m)
{
int i;
int j;
FILE *fp = fopen(fileName, "rb");
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
fscanf(fp, "%d", &arr[i][j]);
}
}
}
处理函数
current表示待处理的线程id,request是该线程的请求资源数组。
void handle(int current, int request[])
{
// 进程任务是否完成
int finish = 1;
for (int i = 0; i < M; i++)
{
if (request[i] > Need[current][i])
{
printf("请求的资源大于需要的资源\n");
return;
}
if (request[i] > Available[i])
{
printf("没有足够的资源可分配\n");
return;
}
}
for (int i = 0; i < M; i++)
{
Available[i] -= request[i];
Allocation[current][i] += request[i];
Need[current][i] -= request[i];
}
// 安全检查
if (!check_secure())
{
//如果检查不通过 回撤改变
for (int i = 0; i < M; i++)
{
Available[i] += request[i];
Allocation[current][i] -= request[i];
Need[current][i] += request[i];
}
printf("安全检查未通过\n");
return;
}
for (int i = 0; i < M; i++)
{
if (Need[current][i] > 0)
{
finish = 0;
break;
}
}
// 如果进程need都为0表示进程完成,回收资源
if (finish)
{
for (int i = 0; i < M; i++)
{
Available[i] += Allocation[current][i];
}
Success[current] = 1;
}
}
安全检查
定义work数组和finish数组。
将work数组初始化等于Available数组,finish数组全部置0表示未完成。
当分配了资源后的cur线程Need[cur]每个元素都小于work,则这个线程可以完成,并将其Need[cur]添加到work里,置finish[cur] = 1。
如果最后finish都为1,表示系统安全。否则不安全。
当系统安全时,finish都为1,以及系统不安全的时候,finish不全为1,但是finish数组已经不会再改变了。如果判断其finish数组不会改变了?
定义一个中间变量flag,如果从第一个线程到最后一个线程中,有线程完成,则flag+1。如果最后循环一轮,flag还是等于0,表示此时finish数组不会再改变了。退出循环,判断系统是否安全。
/**
* 安全检查
*/
int check_secure()
{
// 工作向量
int work[M];
// 完成向量
int finish[N];
// work一开始等于Available, finish全部置0
for (int i = 0; i < M; i++)
{
work[i] = Available[i];
}
for (int i = 0; i < N; i++)
{
finish[i] = 0;
}
printf("安全序列: ");
while (1)
{
// 标识这一轮是否有进程完成
int flag = 0;
for (int i = 0; i < N; i++)
{
// 如果这个进程没有完成,则判断其是否可以完成
if (!finish[i])
{
// temp=0表示可以完成
int temp = 0;
for (int j = 0; j < M; j++)
{
if (Need[i][j] > work[j])
{
temp = 1;
break;
}
}
if (!temp)
{
for (int j = 0; j < M; j++)
{
work[j] += Allocation[i][j];
}
finish[i] = 1;
flag++;
printf("%d ", i);
}
}
}
if (!flag)
{
break;
}
}
printf("\n");
for (int i = 0; i < N; i++)
{
if (!finish[i])
{
// 有不能完成的则为不安全
return 0;
}
}
// 安全返回1
return 1;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)