(环境:VMware软件下的Ubuntu虚拟机)(使用c语言,代码重点部分请添加注释)
(基于“银行家”算法,设计一个死锁避免系统)
当safe函数是int型时,不能返回0和1用来作主函数和其他函数的判断吗?可是如果safe是bool型,我没办法借助SS[s]输出安全序列。可以怎么改呢?
```
安全性检测算法部分源码:
```int safe() {
int work[RNUM];
bool p[PNUM];
int i=0,j=0;
int s;
int ss[5]={0};
for(i=0;i<PNUM;i++)
p[i]=false;
for(j=0; j<RNUM; j++)
work[j]=available[j];
///////is safe state?
int num= PNUM,flag=0;
while ( num-- && flag!=PNUM ){
for (i=0;i<PNUM;i++){
if ( p[i]==true ) {
continue;
}
for ( j=0;j<RNUM;j++){
if ( need[id][j]>work[j] ) break;
}
if ( j==RNUM ) {
flag++;
for ( j=0;j<RNUM;j++){
work[j]+=allocation[i][j];
}
p[i]=true;
ss[s++]=i;
}
}
}
if ( flag==PNUM )
{for(s=0;s<5;s++)
printf("存在一个安全序列:");
printf("%d,",ss[s]);
return 1;}
else
{return 0;}
}
```c
```主函数
int main() {
pid_t pid0,pid1,pid2,pid3,pid4;
while((pid0=vfork())==-1);
if(pid0==0) { //p0 allocation
printf("P0 is allocated<0,0,0>\n");
allocation[0][0]=0;
allocation[0][1]=0;
allocation[0][2]=0;
for(int i=0; i<RNUM; i++) {
need[0][i]=max[0][i]-allocation[0][i];
available[i]-=allocation[0][i];
}
exit(0);
} else { //main process
while((pid1=vfork())==-1);
if(pid1==0) { //p1 allocation
printf("P1 is allocated<0,0,0>\n");
allocation[1][0]=0;
allocation[1][1]=0;
allocation[1][2]=0;
for(int i=0; i<RNUM; i++) {
need[1][i]=max[1][i]-allocation[1][i];
available[i]-=allocation[1][i];
}
exit(0);
} else { //main process
while((pid2=vfork())==-1);
if(pid2==0) { //p2 allocation
printf("P2 is allocated<0,0,0>\n");
allocation[2][0]=0;
allocation[2][1]=0;
allocation[2][2]=0;
for(int i=0; i<RNUM; i++) {
need[2][i]=max[2][i]-allocation[2][i];
available[i]-=allocation[2][i];
}
exit(0);
} else { //main process
while((pid3=vfork())==-1);
if(pid3==0) { //p3 allocation
printf("P3 is allocated<0,0,0>\n");
allocation[3][0]=0;
allocation[3][1]=0;
allocation[3][2]=0;
for(int i=0; i<RNUM; i++) {
need[3][i]=max[3][i]-allocation[3][i];
available[i]-=allocation[3][i];
}
exit(0);
} else { //main process
while((pid4=vfork())==-1);
if(pid4==0) { //p3 allocation
printf("P4 is allocated<0,0,0>\n");
allocation[4][0]=0;
allocation[4][1]=0;
allocation[4][2]=0;
for(int i=0; i<RNUM; i++) {
need[4][i]=max[4][i]-allocation[4][i];
available[i]-=allocation[4][i];
}
exit(0);
} else
{display();
if(safe()==1) printf("The system is safe now!\n");
else printf("The system is not safe\n");}
//////test banker()
banker();
exit(0);
}
}
}
}
return EXIT_SUCCESS;;}
按你的样例代码修改了一下,有什么问题可以找我
/*
* 银行家算法的模拟。
* 2022/12/5 created by senllang
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
//#include<sys/syscall.h>
#define PNUM 5 /* 申请者数量 */
#define RNUM 3 /* 资源类型数量 */
/* 当前资源的可用数量,初始值为最大资源数量 */
int available[RNUM] = {10, 5, 7};
/* 已经分配的资源列表,初始值合为0 */
int allocation[PNUM][RNUM] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
/* 每种资源,对于每个申请者最大可申请的数量,为预设值 */
int max[PNUM][RNUM] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};
/* 每个申请者需要的资源数量 */
int need[PNUM][RNUM] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};
/*
* 记录安全路径。
*/
static int safePath[PNUM] = {0};
/* 记录申请记录 */
struct recordData
{
int pnum;
int allocated[RNUM];
};
#define MAX_HISTORY_RECORE_NUM 100
struct recordList
{
int offset;
struct recordData record[MAX_HISTORY_RECORE_NUM];
};
static struct recordList historyAllocated = {0};
void displaySafePath()
{
printf("safe check path:\n");
for(int i = 0; i < PNUM; i++)
printf("P%-9d\t", safePath[i]);
printf("\n");
}
void displayAllocatedHistory()
{
printf("The history record of allocated :\n");
printf("%-3s\t%-10s\t%-10s\n","NO ","process", "allocation");
for(int i = 0; i < historyAllocated.offset; i++)
{
int j = 0;
printf("%-3d\tP%-9d\t",i,historyAllocated.record[i].pnum);
for (j = 0; j < RNUM; j++)
printf("%2d ", historyAllocated.record[i].allocated[j]);
}
}
void insertHistory(int pnum, int req[])
{
if(historyAllocated.offset >= MAX_HISTORY_RECORE_NUM)
{
printf("The list of history is full.\n");
return ;
}
historyAllocated.record[historyAllocated.offset].pnum = pnum;
for(int i = 0; i < RNUM; i++)
historyAllocated.record[historyAllocated.offset].allocated[i] = req[i];
historyAllocated.offset++;
}
void display()
{
printf("The resource state now:\n");
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "process", " max", "allocation", " need", "available");
for (int i = 0; i < PNUM; i++)
{
int j = 0;
printf("P%-9d\t", i);
for (j = 0; j < RNUM; j++)
printf("%2d ", max[i][j]);
printf("\t");
for (j = 0; j < RNUM; j++)
printf("%2d ", allocation[i][j]);
printf("\t");
for (j = 0; j < RNUM; j++)
printf("%2d ", need[i][j]);
printf("\t");
if (i == 0)
for (j = 0; j < RNUM; j++)
printf("%2d ", available[j]);
printf("\n");
}
}
void rollback(int req[], int id)
{
int j = 0;
for (j = 0; j < RNUM; j++)
{ // rollback if a process's request is not allowed
allocation[id][j] -= req[j];
need[id][j] += req[j];
available[j] += req[j];
}
}
void request(int req[], int id)
{ // resource request
int j = 0;
///////update state
for (j = 0; j < RNUM; j++)
{
allocation[id][j] += req[j];
need[id][j] -= req[j];
available[j] -= req[j];
}
}
bool issafe()
{
int work[RNUM];
bool finish[PNUM];
int i = 0, j = 0;
int safePathOffset = 0;
/* 每次使用前,先赋初值;finish[]全部为false; work[]为available[] */
for (i = 0; i < PNUM; i++)
finish[i] = false;
for (j = 0; j < RNUM; j++)
work[j] = available[j];
for (i = 0; i < PNUM; i++)
safePath[i] = 0;
///////is safe state?
int num = PNUM, flag = 0;
while (num-- && flag != PNUM)
{
/* 尝试一遍检查,最多尝试num遍的检查。每遍检查把当前符合的申请者标记出来。 */
for (i = 0; i < PNUM; i++)
{
/* 跳过已经安全检查过的申请者 */
if (finish[i] == true)
continue;
/* 查找下一个符合的申请者 */
for (j = 0; j < RNUM; j++)
{
/*
* 如果有一种资源需求大于当前可用资源数量,
* 那么不再继续比较其它资源。
*/
if (need[i][j] > work[j])
break;
}
/*
* RNUM个资源都符合的情况,那么work中增加该申请者已经占用的资源。
* 也就是假设该申请者释放全部持有资源后,下一个申请者的可用资源数量。
*/
if (j == RNUM)
{
flag++;
for (j = 0; j < RNUM; j++)
{
work[j] += allocation[i][j];
}
finish[i] = true;
safePath[safePathOffset++] = i;
}
}
}
/* 如果所有申请者都符合,那么返回true,否则返回false */
if (flag == PNUM)
return true;
else
return false;
}
bool banker()
{
int request[RNUM] = {0};
int i = 0, j = 0, id;
while (true)
{
printf("Please input a process id :\n P");
scanf("%d", &id);
if (id < 0 || id >= PNUM)
{
printf("invalid process!\n");
break;
}
printf("Please input request array for P%d :\n", id);
for (j = 0; j < RNUM; j++)
{
scanf("%d", &request[j]);
if (request[j] < 0)
{
printf("invalid request!\n");
return false;
}
}
//////////banker algorithm
for (j = 0; j < RNUM; j++)
{
if (request[j] > need[id][j])
{
printf("请求大于所需的资源\n");
break;
}
if (request[j] > available[j])
{
printf("请求大于剩余资源\n");
break;
}
}
if (j == RNUM)
{
for (i = 0; i < RNUM; i++)
{
available[i] -= request[i];
allocation[id][i] += request[i];
need[id][i] -= request[i];
}
if (issafe() == false)
{
rollback(&request[0], id);
printf("该请求会造成不安全\n");
}
else if (issafe() == true)
{
insertHistory(id, request);
printf("可以申请,结果如下\n");
display();
displaySafePath();
}
}
}
return true;
}
int main()
{
pid_t pid0, pid1, pid2, pid3, pid4;
while ((pid0 = vfork()) == -1)
;
if (pid0 == 0)
{ // p0 allocation
printf("P0 is allocated<0,1,0>\n");
allocation[0][0] = 0;
allocation[0][1] = 1;
allocation[0][2] = 0;
for (int i = 0; i < RNUM; i++)
{
need[0][i] = max[0][i] - allocation[0][i];
available[i] -= allocation[0][i];
}
exit(0);
}
else
{ // main process
while ((pid1 = vfork()) == -1)
;
if (pid1 == 0)
{ // p1 allocation
printf("P1 is allocated<2,0,0>\n");
allocation[1][0] = 2;
allocation[1][1] = 0;
allocation[1][2] = 0;
for (int i = 0; i < RNUM; i++)
{
need[1][i] = max[1][i] - allocation[1][i];
available[i] -= allocation[1][i];
}
exit(0);
}
else
{ // main process
while ((pid2 = vfork()) == -1)
;
if (pid2 == 0)
{ // p2 allocation
printf("P2 is allocated<3,0,2>\n");
allocation[2][0] = 3;
allocation[2][1] = 0;
allocation[2][2] = 2;
for (int i = 0; i < RNUM; i++)
{
need[2][i] = max[2][i] - allocation[2][i];
available[i] -= allocation[2][i];
}
exit(0);
}
else
{ // main process
while ((pid3 = vfork()) == -1)
;
if (pid3 == 0)
{ // p3 allocation
printf("P3 is allocated<2,1,1>\n");
allocation[3][0] = 2;
allocation[3][1] = 1;
allocation[3][2] = 1;
for (int i = 0; i < RNUM; i++)
{
need[3][i] = max[3][i] - allocation[3][i];
available[i] -= allocation[3][i];
}
exit(0);
}
else
{ // main process
while ((pid4 = vfork()) == -1)
;
if (pid4 == 0)
{ // p3 allocation
printf("P4 is allocated<0,0,2>\n");
allocation[4][0] = 0;
allocation[4][1] = 0;
allocation[4][2] = 2;
for (int i = 0; i < RNUM; i++)
{
need[4][i] = max[4][i] - allocation[4][i];
available[i] -= allocation[4][i];
}
exit(0);
}
else
{ // main process
display();
if (issafe() == true)
{
printf("The system is safe now!\n");
}
else
printf("The system is not safe\n");
//////test banker()
banker();
displayAllocatedHistory();
exit(0);
}
}
}
}
}
return EXIT_SUCCESS;
}
避免死锁-----银行家算法详解
https://blog.csdn.net/qq_34666857/article/details/104131832