银行家算法(链表)

该博客详细介绍了使用链表实现的银行家算法,包括程序模块、流程、主要函数说明。首先,通过初始化进程链表并打印进程信息,然后运用安全性算法检查系统是否安全。如果安全,会进行试分配并检查试分配后的安全性。主要函数如插入链表、初始化、打印系统资源等被详细阐述。最后,博客展示了程序设计流程图、测试结果和源代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.程序模块及流程
(1)本程序中重要模块主要包括以下模块:
1初始化void Init()
2安全性算法int Safety_Algorithm()
3试分配process* Attempt()
4测试void TestBanker()
(2)执行流程:
此银行家算法运用了链表来实现,首先建立进程链表块,每一个节点代表一个进程信息,每个进程的资源信息为数据结构中的数据信息。
1进行进程的初始化,存储当前的进程信息
2将信息打印输出在屏幕上
3调用安全性算法,检测当前系统是否处于安全状态,若处于安全状态,则进行下一步,若不安全则程序结束
4调用试分配函数,进行试分配,若试分配成功,修改相关数据结构,打印当前系统资源情况表,进行下一步,否则,重新接收其他请求向量。
5再次调用安全性算法,检查试分配以后的系统安全性,若安全则打印安全性序列和系统资源情况表,并选择是否继续操作。否则之前的试分配失败,返回试分配之前的数据结构,输出系统资源情况表,接收下一个进程请求。

二.主要函数说明:
void Insret_Tail(process **head, process node);//链表尾插
void Init(process **head, int m); //初始化系统资源
void Print(process *head, int *avail, int m);//打印当前系统资源情况表
void PrintSafety(process *head, int *safety, int work[][M], int m, int n);//打印试分配后安全状态的资源情况表
process* Location(process* head, int pro_num);//进程定位
process* Attempt(process* head, int *request, int *avail, int m);//试分配
process* CurRun(process* head, int*finish, int*work, int m, int n);//找到当前可执行进程(通过安全检查的进程)
void Change(process* p, int* work, int* finish, int record[][M], int m);//修改进程书信息
int Safety_Algorithm(process* head, int *avail, int *safety, int Record[][M], int m, int n);//安全性算法
void Back(process* p, int *request, int *avail, int m);//试分配失败后恢复分配前系统资源
void TestBanker();//测试函数

三.程序设计流程图:
这里写图片描述

四.测试结果:

初始化进程信息测试

试分配测试

这里写图片描述

非法请求失败

这里写图片描述

这里写图片描述

五.源代码:

//banker.h
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define M 50 // 系统资源的种类
#define N 50 // 最大进程数
int n = 0;
typedef struct my_process
{
    int num;                    //进程标号  
    int Max[M];                 // 表示某个进程对某类资源的最大需求
    int Allocation[M];          // 表示某个进程已分配到某类资源的个数
    int Need[M];                // 表示某个进程尚需要某类资源的个数
    struct my_process* next;            //指向下一个进程节点
}process;

void Insret_Tail(process **head, process node)    //尾插法建立进程链表
{
    process* p = (process*)malloc(sizeof(process));
    process* last = NULL;
    memcpy(p, &node, sizeof(process));     //动态创建进程结点
    p->next = NULL;
    if (NULL == *head)
    {
        *head = p;
    }
    else      //找表尾
    {
        last = *head;
        while (last->next != NULL)
        {
            last = last->next;
        }
        last->next = p;             //插入链尾
    }

}

void Init(process **head, int m)//初始化系统资源
{
    int n1 = n;
    int i, j = 0;
    for (int z = 0; z < n1; z++)
    {
        process node;
        node.num = j++;
        printf("请输入第 %d个进程信息 :\n", z + 1);
        printf("最大需求矩阵: ");
        for (i = 0; i<m; i++)
        {
            scanf_s("%d", &node.Max[i]);
        }
        printf("分配矩阵: ");
        for (i = 0; i<m; i++)
        {
            scanf_s("%d", &node.Allocation[i]);
        }
        printf("\n");
        for (i = 0; i<m; i++)
        {
            node.Need[i] = node.Max[i] - node.Allocation[i];
        }
        Insret_Tail(head, node);  //插入链尾
    }
}

void Print(process *head, int *avail, int m)//打印初始系统资源
{
    process* p = NULL;
    int count = 0;
    int i, j;
    char ch;
    p = head;
    if (NULL == p)
    {
        printf("当前无进程 !\n");
        return;
    }
    else
    {
        printf("资源分配情况表:\n");
        printf("\n    |num|     |Max|       |Allocation|      | Need |      |Available| \n");
        printf("\t");
        for (i = 0; i<4; i++)
        {
            ch = 'A';
            for (j = 0; j<m; j++)
            {
                printf("%4c", ch++);
            }
            printf("\t");
        }

        printf("\n");
        while (p != NULL)
        {
            count++;
            printf("%8d", p->num);
            for (j = 0; j<m; j++)
            {
                printf("%4d", p->Max[j]);
            }
            printf("\t");
            for (j = 0; j<m; j++)
            {
                printf("%4d", p->Allocation[j]);
            }
            printf("\t");
            for (j = 0; j<m; j++)
            {
                printf("%4d", p->Need[j]);
            }
            printf("\t");
            if (count == 1)
            {
                for (j = 0; j<m; j++)
                {
                    printf("%4d", avail[j]);
                }
            }
            printf("\n");
            p = p->next;
        }
        printf("\n");
    }
}

void PrintSafety(process *head, int *safety, int work[][M], int m, int n)  //打印试分配后的系统资源状态
{
    process* p = NULL;
    int i, j;
    p = head;
    if (NULL == p)
    {
        exit(0);
    }
    else
    {
        printf("\n                                                            |Work+|               ");
        printf("\n|Process|   |Work|         |Need|        |Allocation|    |Allocation|  |Finish|\n");
        puts("");
        for (i = 0; i<n; i++)
        {
            p = head;
            while (p != NULL)
            {
                if (p->num == safety[i])
                {
                    printf("%8d", p->num);
                    for (j = 0; j<m; j++)
                    {
                        printf("%4d", work[p->num][j]);
                    }
                    printf("\t");
                    for (j = 0; j<m; j++)
                    {
                        printf("%4d", p->Need[j]);
                    }
                    printf("\t");
                    for (j = 0; j<m; j++)
                    {
                        printf("%4d", p->Allocation[j]);
                    }
                    printf("\t");
                    for (j = 0; j<m; j++)
                    {
                        printf("%4d", work[p->num][j] + p->Allocation[j]);
                    }
                    for (j = 0; j<m - 2; j++)
                    {
                        printf("\ttrue");
                    }
                    break;
                }
                else
                {
                    p = p->next;
                }
            }
            puts("");
        }
    }
}

process* Location(process* head, int pro_num)   //进程定位函数,找到当前请求进程在进程链表中的位置,以便后面对其操作
{
    process *p = NULL;
    p = head;
    if (NULL == p)
    {
        printf("error !\n");            //异常,当前链表为空
        return p;
    }
    else
    {
        while (p != NULL)
        {
            if (p->num == pro_num)
            {
                break;
            }
            else
            {
                p = p->next;
            }
        }
        if (NULL == p)              //无此进程,输入错误
        {
            printf("无此进程 !\n");
            return p;
        }
        else
        {
            return p;
        }
    }
}

process* Attempt(process* head, int *request, int *avail, int m)//试分配
{
    int num, i;
    process* p = NULL;
    printf("请输入进程编号: \n");
    scanf_s("%d", &num);
    p = Location(head, num);
    if (NULL == p)
    {
        printf("无此进程!\n");
        return p;
    }
    printf("请输入该进程的请求向量: \n");
    for (i = 0; i<m; i++)
    {
        scanf_s("%d", &request[i]);
    }
    for (i = 0; i<m; i++)       //请求的合法性检验
    {
        if (request[i] <= p->Need[i])
        {
            continue;
        }
        else
        {
            printf("该请求系统不能满足 !\n");
            return NULL;
        }
    }
    for (i = 0; i<m; i++)
    {
        if (request[i] <= avail[i])
        {
            continue;
        }
        else
        {
            printf("该请求系统不能满足 !\n");
            return NULL;
        }
    }
    for (i = 0; i<m; i++)                     //试分配,修改相关数据结构
    {
        avail[i] = avail[i] - request[i];
        p->Allocation[i] = p->Allocation[i] + request[i];
        p->Need[i] = p->Need[i] - request[i];
    }
    return p;
}

process* CurRun(process* head, int*finish, int*work, int m, int n)//找当前可执行的进程
{
    int i = 0, j = 0, count = 0;
    process* p = NULL;
    while (1)
    {
        if (finish[i] != -1)  //表示该进程未执行安全性检查
        {
            p = Location(head, finish[i]);      //定位该进程
            if (p != NULL)
            {
                for (j = 0; j<m; j++)
                {
                    if (p->Need[j]>work[j])
                    {

                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
                if (j == m)
                {
                    return p;
                }
                else
                {
                    i++;    //当前进程检查没有通过,则进行下一个进程的检查
                }
            }
        }
        else
        {
            i++;   //当前进程已经检查过,则进行下一个进程的检查
        }
        if (i == n)
        {
            return NULL;  //遍历所有进程都未找到,则跳出返回NULL
        }
    }
}

void Change(process* p, int* work, int* finish, int record[][M], int m) //修改相关数据结构
{
    int i;
    for (i = 0; i<m; i++)
    {
        record[p->num][i] = work[i];
        work[i] = work[i] + p->Allocation[i];

    }
    finish[p->num] = -1;   //表示该进程已通过安全性检查
}

int Safety_Algorithm(process* head, int *avail, int *safety, int Record[][M], int m, int n)//安全性算法
{
    int *work = NULL;
    int *finish = NULL;
    process *p = NULL;
    process *pro = NULL;
    int i, count = 0;
    work = (int*)malloc(m*sizeof(int));     //当前系统可供给进程的各个资源数目
    finish = (int*)malloc(n*sizeof(int));       //标志数组

    p = head;
    for (i = 0; i<m; i++)
    {
        work[i] = avail[i];
    }
    i = 0;
    while (p != NULL)
    {

        finish[i] = p->num;
        p = p->next;
        i++;
    }
    i = 0;
    while (count<n)
    {
        pro = CurRun(head, finish, work, m, n);
        if (pro != NULL)    //Need[i,j]<=work[j],即当前系统可以满足该进程
        {
            Change(pro, work, finish, Record, m);
            count++;
            safety[i] = pro->num;
            i++;
        }
        else
        {
            printf("当前系统处于不安全状态 !\n");
            break;
        }

    }
    if (count == n)
    {
        printf("当前系统处于安全状态,存在一个安全序列 :\n");
        for (i = 0; i<n; i++)
        {
            printf("%d,", safety[i]);     //打印安全序列
        }
        puts("");
    }

    free(finish);
    free(work);
    finish = NULL;
    work = NULL;
    if (count == n)
    {
        return 1;   //找到安全序列则返回1
    }
    else
    {
        return 0;   //未找到安全序列则返回0
    }
}

void Back(process* p, int *request, int *avail, int m)  //若试分配失败,则恢复试分配前的资源状态
{
    int i;
    {
        for (i = 0; i<m; i++)
        {
            p->Allocation[i] -= request[i];
            p->Need[i] += request[i];
            avail[i] += request[i];
        }
    }
}
#include"banker.h"
void TestBanker()
{
    int i, flag = 0, count = 0;
    char ch;
    int mM;
    int *p = NULL;      //进程链头指针数组
    int Available[M] = { 0 };/*其中每一个数组元素表示当前某类资源的可用数目,初始化为系统所提供的资源的最大数目*/
    int Request[M] = { 0 };
    int Record_work[N][M] = { 0 };
    int Safety[N] = { 0 };   //存储安全序列,以便后面排序
    process *head = NULL;
    process *pro = NULL;
    printf("请输入进程个数:");
    scanf_s("%d", &n);
    printf("请输入资源数目:");
    scanf_s("%d", &mM);
    printf("\n请初始化当前可用资源\n");
    for (i = 0; i<mM; i++)
    {
        scanf_s("%d", &Available[i]);
    }
    Init(&head, mM);
    Print(head, Available, mM);
    do
    {
        flag = Safety_Algorithm(head, Available, Safety, Record_work, mM, n);
        if (1 == flag)
        {
            printf("当前系统是安全的,可进行试探分配 !\n");
            do
            {
                pro = Attempt(head, Request, Available, mM);     //通过则试分配
                if (NULL != pro)
                {
                    printf("试分配成功 !\n");
                    Print(head, Available, mM);
                    break;
                }
                else                            // 否则,退到上一级
                {
                    printf("当前请求系统不能满足 ! 请重新输入请求向量(Y/y),或者退出(N/n)\n\n");
                    printf("您是否要继续操作 (Y/N):\n");
                    getchar();
                    scanf_s("%c", &ch);
                    if (ch == 'N' || ch == 'n')
                    {
                        exit(0);
                    }
                }
            } while (ch == 'Y' || ch == 'y');
        }
        else        //未通过安全性算法
        {

            printf("当前系统不安全,不能响应任何进程的请求 !\n");
            return;
        }
        flag = Safety_Algorithm(head, Available, Safety, Record_work, mM, n);
        if (1 == flag)
        {
            printf("分配成功!当前资源分配状态如下表 :\n");
            PrintSafety(head, Safety, Record_work, mM, n);
            printf("您是否还要继续操作 (Y(y)/N(y))\n");
            getchar();
            scanf_s("%c", &ch);
        }
        else
        {
            printf("当前系统处于不安全状态,恢复原来的资源分配状态 ! :\n");
            Back(pro, Request, Available, mM);
            Print(head, Available, mM);
            printf("您是否还要继续操作 (Y(y)/N(y))\n");
            getchar();
            scanf_s("%c", &ch);
        }
    } while (ch == 'Y' || ch == 'y');
}

int main()
{
    TestBanker();
    system("pause");
    return 0;
}
操作系统课的实验(银行家算法)#include "malloc.h"   #include "stdio.h"   #include "stdlib.h"   #define alloclen sizeof(struct allocation)   #define maxlen sizeof(struct max)   #define avalen sizeof(struct available)   #define needlen sizeof(struct need)   #define finilen sizeof(struct finish)   #define pathlen sizeof(struct path)   struct allocation   {   int value;   struct allocation *next;   };   struct max   {   int value;   struct max *next;   };   struct available /*可用资源数*/   {   int value;   struct available *next;   };   struct need /*需求资源数*/   {   int value;   struct need *next;   };   struct path   {   int value;   struct path *next;   };   struct finish   {   int stat;   struct finish *next;   };   int main()   {   int row,colum,status=0,i,j,t,temp,processtest;   struct allocation *allochead,*alloc1,*alloc2,*alloctemp;   struct max *maxhead,*maxium1,*maxium2,*maxtemp;   struct available *avahead,*available1,*available2,*workhead,*work1,*work2,*worktemp,*worktemp1;   struct need *needhead,*need1,*need2,*needtemp;   struct finish *finihead,*finish1,*finish2,*finishtemp;   struct path *pathhead,*path1,*path2;   printf("\n请输入系统资源的种类数:");   scanf("%d",&colum);   printf("请输入现时内存中的进程数:");   scanf("%d",&row);   printf("请输入已分配资源矩阵:\n");   for(i=0;i<row;i++)   {   for (j=0;jnext=alloc2->next=NULL;   scanf("%d",&allochead->value);   status++;   }   else   {   alloc2=(struct allocation *)malloc(alloclen);   scanf("%d,%d",&alloc2->value);   if(status==1)   {   allochead->next=alloc2;   status++;   }   alloc1->next=alloc2;   alloc1=alloc2;   }   }   }   alloc2->next=NULL;   status=0;   printf("请输入最大需求矩阵:\n");   for(i=0;i<row;i++)   {   for (j=0;jnext=maxium2->next=NULL;   scanf("%d",&maxium1->value);   status++;   }   else   {   maxium2=(struct max *)malloc(maxlen);   scanf("%d,%d",&maxium2->value);   if(status==1)   {   maxhead->next=maxium2;   status++;   }   maxium1->next=maxium2;   maxium1=maxium2;   }   }   }   maxium2->next=NULL;   status=0;   printf("请输入现时系统剩余的资源矩阵:\n");   for (j=0;jnext=available2->next=NULL;   work1->next=work2->next=NULL;   scanf("%d",&available1->value);   work1->value=available1->value;   status++;   }   else   {   available2=(struct available*)malloc(avalen);   work2=(struct available*)malloc(avalen);   scanf("%d,%d",&available2->value);   work2->value=available2->value;   if(status==1)   {   avahead->next=available2;   workhead->next=work2;   status++;   }   available1->next=available2;   available1=available2;   work1->next=work2;   work1=work2;   }   }   available2->next=NULL;   work2->next=NULL;   status=0;   alloctemp=allochead;   maxtemp=maxhead;   for(i=0;i<row;i++)   for (j=0;jnext=need2->next=NULL;   need1->value=maxtemp->value-alloctemp->value;   status++;   }   else   {   need2=(struct need *)malloc(needlen);   need2->value=(maxtemp->value)-(alloctemp->value);   if(status==1)   {   needhead->next=need2;   status++;   }   need1->next=need2;   need1=need2;   }   maxtemp=maxtemp->next;   alloctemp=alloctemp->next;   }   need2->next=NULL;   status=0;   for(i=0;inext=finish2->next=NULL;   finish1->stat=0;   status++;   }   else   {   finish2=(struct finish*)malloc(finilen);   finish2->stat=0;   if(status==1)   {   finihead->next=finish2;   status++;   }   finish1->next=finish2;   finish1=finish2;   }   }   finish2->next=NULL; /*Initialization compleated*/   status=0;   processtest=0;   for(temp=0;temp<row;temp++)   {   alloctemp=allochead;   needtemp=needhead;   finishtemp=finihead;   worktemp=workhead;   for(i=0;istat==0)   {   for(j=0;jnext,worktemp=worktemp->next)   if(needtemp->valuevalue)   processtest++;   if(processtest==colum)   {   for(j=0;jvalue+=alloctemp->value;   worktemp1=worktemp1->next;   alloctemp=alloctemp->next;   }   if(status==0)   {   pathhead=path1=path2=(struct path*)malloc(pathlen);   path1->next=path2->next=NULL;   path1->value=i;   status++;   }   else   {   path2=(struct path*)malloc(pathlen);   path2->value=i;   if(status==1)   {   pathhead->next=path2;   status++;   }   path1->next=path2;   path1=path2;   }   finishtemp->stat=1;   }   else   {   for(t=0;tnext;   finishtemp->stat=0;   }   }   else   for(t=0;tnext;   alloctemp=alloctemp->next;   }   processtest=0;   worktemp=workhead;   finishtemp=finishtemp->next;   }   }   path2->next=NULL;   finishtemp=finihead;   for(temp=0;tempstat==0)   {   printf("\n系统处于非安全状态!\n");   exit(0);   }   finishtemp=finishtemp->next;   }   printf("\n系统处于安全状态.\n");   printf("\n安全序列为: \n");   do   {   printf("p%d ",pathhead->value);   }   while(pathhead=pathhead->next);   printf("\n");   return 0;   } #include "string.h" #include #include #define M 5 #define N 3 #define FALSE 0 #define TRUE 1 /*M个进程对N类资源最大资源需求量*/ int MAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}}; /*系统可用资源数*/ int AVAILABLE[N]={10,5,7}; /*M个进程对N类资源最大资源需求量*/ int ALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; /*M个进程已经得到N类资源的资源量 */ int NEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}}; /*M个进程还需要N类资源的资源量*/ int Request[N]={0,0,0}; void main() { int i=0,j=0; char flag='Y'; void showdata(); void changdata(int); void rstordata(int); int chkerr(int); showdata(); while(flag=='Y'||flag=='y') { i=-1; while(i=M) { printf("请输入需申请资源的进程号(从0到"); printf("%d",M-1); printf(",否则重输入!):"); scanf("%d",&i); if(i=M)printf("输入的进程号不存在,重新输入!\n"); } printf("请输入进程"); printf("%d",i); printf("申请的资源数\n"); for (j=0;jNEED[i][j]) { printf("进程"); printf("%d",i); printf("申请的资源数大于进程"); printf("%d",i); printf("还需要"); printf("%d",j); printf("类资源的资源量!申请不合理,出错!请重新选择!\n"); /*printf("申请不合理,出错!请重新选择!\n");*/ flag='N'; break; } else { if(Request[j]>AVAILABLE[j]) { printf("进程"); printf("%d",i); printf("申请的资源数大于系统可用"); printf("%d",j); printf("类资源的资源量!申请不合理,出错!请重新选择!\n"); /*printf("申请不合理,出错!请重新选择!\n");*/ flag='N'; break; } } } if(flag=='Y'||flag=='y') { changdata(i); if(chkerr(i)) { rstordata(i); showdata(); } else showdata(); } else showdata(); printf("\n"); printf("是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示: "); scanf("%c",&flag); } } void showdata() { int i,j; printf("系统可用的资源数为:\n"); printf(" "); for (j=0;j<N;j++){ printf(" 资源"); printf("%d",j); printf(":"); printf("%d",AVAILABLE[j]); /*printf("\n");*/ /* cout<<endl; // cout<<"各进程资源的最大需求量:"<<endl<<endl; // for (i=0;i<M;i++) // { // cout<<"进程"<<i<<":"; // for (j=0;j<N;j++)cout<<" 资源"<<j<<": "<<MAX[i][j]; // cout<<endl; */ } printf("\n"); printf("各进程还需要的资源量:\n"); for (i=0;i<M;i++) { printf(" 进程"); printf("%d",i); printf(":"); for (j=0;j<N;j++){ printf("资源"); printf("%d",j); printf(":"); printf("%d",NEED[i][j]); /*printf("\n");*/ } printf("\n"); } printf("各进程已经得到的资源量: \n"); for (i=0;i<M;i++) { printf(" 进程"); printf("%d",i); /*printf(":\n");*/ for (j=0;j<N;j++){ printf("资源"); printf("%d",j); printf(":"); printf("%d",ALLOCATION[i][j]); /*printf("\n");*/ } printf("\n"); } } void changdata(int k) { int j; for (j=0;j<N;j++) { AVAILABLE[j]=AVAILABLE[j]-Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j]; NEED[k][j]=NEED[k][j]-Request[j]; } }; void rstordata(int k) { int j; for (j=0;j<N;j++) { AVAILABLE[j]=AVAILABLE[j]+Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j]; NEED[k][j]=NEED[k][j]+Request[j]; } }; int chkerr(int s) { int WORK,FINISH[M],temp[M]; int i,j,k=0; for(i=0;i<M;i++)FINISH[i]=FALSE; for(j=0;j<N;j++) { WORK=AVAILABLE[j]; i=s; while(i<M) { if (FINISH[i]==FALSE&&NEED[i][j]<=WORK) { WORK=WORK+ALLOCATION[i][j]; FINISH[i]=TRUE; temp[k]=i; k++; i=0; } else { i++; } } for(i=0;i<M;i++) if(FINISH[i]==FALSE) { printf("\n"); printf("系统不安全!!! 本次资源申请不成功!!!\n"); printf("\n"); return 1; } } printf("\n"); printf("经安全性检查,系统安全,本次分配成功。\n"); printf("\n"); printf(" 本次安全序列:"); for(i=0;i"); } printf("\n"); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值