2021-11-16 11:02阅读: 438评论: 0推荐: 0

操作系统——银行家算法的模拟实现

一、实验目的

(1)理解银行家算法。
(2)掌握进程安全性检查的方法与资源分配的方法。

二、实验内容与基本要求

编制模拟银行家算法的程序,并给出一个例子验证所编写的程序的正确性。
要求例子中包含分配安全和不安全的两种情况,输出清晰明了。

三、实验报告内容

1.银行家算法和安全性检查算法原理

(1) 银行家算法

用来避免死锁。实现银行家算法,每个新进程在进入系统时它必须申明在运行过程中,可能需要的每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当某一进程请求时,系统会自动判断请求量是否小于进程最大所需,同时判断请求量是否小于当前系统资源剩余量。若两项均满足,则系统试分配资源并执行安全性检查算法。

在这里插入图片描述

(2) 安全性检查算法

用于检查系统进行资源分配后是否安全。在系统试分配资源后,算法从现有进程列表寻找出一个可执行的进程进行执行,执行完成后回收进程占用资源;进而寻找下一个可执行进程。当进程需求量大于系统可分配量时,进程无法执行。当所有进程均可执行,则产生一个安全执行序列,系统资源分配成功。若进程无法全部执行,即无法找到一条安全序列,所以此次分配失败。

四、程序代码

//编制模拟银行家算法的程序,并给出一个例子验证所编写的程序的正确性。
//要求例子中包含分配安全和不安全的两种情况,输出清晰明了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 300
#define maxm 300
int n, m;                   //n为进程的个数,m为资源类型的个数
int Available[maxm];        //可利用资源向量
int Max[maxn][maxm];        //最大需求矩阵
int Allocation[maxn][maxm]; //分配矩阵
int Need[maxn][maxm];       //需求矩阵
int Request[maxm],id;       //请求向量
int ssj[maxn];               //n个进程完成情况
int work[maxm];             //工作空间
int Queue[maxn], Qi;        //存安全队列

bool RN(int k){//第k个进程需求资源小于声明需求
    for (int i = 0; i < m;i++){
        if(Request[i]>Need[k][i]) return 0;
    }
    return 1;
}
bool RA(int k){//第k个进程需求资源小于可利用资源
    for (int i = 0; i < m;i++){
        if(Request[i]>Available[i]) return 0;
    }
    return 1;
}
void fenpei(int k){//分配资源
    for (int i = 0; i < m;i++){
        Available[i] -= Request[i];
    }
    for (int i = 0; i < m;i++){
        Allocation[k][i] += Request[i];
    }
    for (int i = 0; i < m;i++){
        Need[k][i] -= Request[i];
    }
}

void chexiao(int k){
    for (int i = 0; i < m;i++){
        Available[i] += Request[i];
    }
    for (int i = 0; i < m;i++){
        Allocation[k][i] -= Request[i];
        
    }
    for (int i = 0; i < m;i++){
        Need[k][i] += Request[i];
    }
}

void print(){
    printf("--------------当前进程、资源情况--------------\n");
    printf("\t%10s%16s%10s\n","Max","allocation","Need");
    printf("进程名\t");
    for (int x = 0; x < 3;x++){
        printf("      ");
        for (int i = 0; i < m; i++)
            printf("%2c", 'a' + i);
    }
    printf("\n");
    for (int i = 0; i < n;i++){
        printf("    %d   ", i);
        printf("      ");
        for (int j = 0; j < m; j++)
            printf("%2d", Max[i][j]);
        printf("      ");
        for (int j = 0; j < m; j++)
            printf("%2d", Allocation[i][j]);
        printf("      ");
        for (int j = 0; j < m; j++)
            printf("%2d", Need[i][j]);
        printf("\n");
    }
    printf("系统可利用资源:");
    for (int i = 0; i < m;i++)
        printf("%3d", Available[i]);
    printf("\n ---------------------------------------------\n");
}

bool issafe(){//安全性算法
    memset(ssj, 0, sizeof(ssj));
    memcpy(work, Available, sizeof(int) * (m+1));
    Qi = 0;
    for (int i = 0; i < n;i++){
        if(ssj[i]) continue;
        int j;
        for (j = 0; j < m;j++){
            if(Need[i][j]>work[j])
                break;
        }
        if(j==m){
            for (j = 0; j < m;j++){
                work[j] += Allocation[i][j];
            }
            ssj[i] = 1;
            Queue[Qi++] = i;
            i = -1;
        }
    }
    for (int i = 0; i < n;i++){
        if(!ssj[i]) return 0;   
    }    
    return 1;
}

int Dijkstra(){
    if(issafe()==0){
        printf("初始数据不安全\n");
        return 1;
    }
    while(1){
        printf("\n请输入一个请求进程的id和请求进程各个资源的量:\n");
        scanf("%d", &id);
        for (int i = 0; i < m;i++){
            scanf("%d", &Request[i]);
        }
        if(RN(id)){//判断小于声明的
            if(!RA(id))//大于系统资源
                printf("尚无足够资源,进程须等待\n");
            else{
                fenpei(id);
                if(issafe()){//分配资源
                    printf("存在一个安全队列:");
                    for (int i = 0; i < Qi;i++){
                        if(i) printf("->");
                        printf("%d", Queue[i]);
                    }
                    printf("\n分配成功!\n");
                    print();
                }else{
                    chexiao(id);
                    printf("不安全,不给分配!\n");
                }
            } 
        }else{
            printf("出错,所需资源超过声明最大资源\n");
        }   
    }
}

int main()
{
    printf("请输入进程数和资源数:\n");
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n;i++){
        for (int j = 0; j < m;j++)
            scanf("%d", &Max[i][j]);
        for (int j = 0; j < m;j++)
            scanf("%d", &Allocation[i][j]);
        for (int j = 0; j < m;j++)
            Need[i][j] = Max[i][j] - Allocation[i][j];
    }
    printf("请输入系统可利用资源:\n");
    for (int i = 0; i < m;i++)
        scanf("%d", &Available[i]);
    print();
    Dijkstra();
    return 0;
}
/*
请输入进程数和资源数:
5 3
7 5 3 0 1 0
3 2 2 2 0 0
9 0 2 3 0 2
2 2 2 2 1 1
4 3 3 0 0 2
请输入系统可利用资源:
3 3 2
*/
*/

五、实验结果

在这里插入图片描述

请输入进程数和资源数:
5 3
7 5 3 0 1 0
3 2 2 2 0 0
9 0 2 3 0 2
2 2 2 2 1 1
4 3 3 0 0 2
请输入系统可利用资源:
3 3 2
--------------当前进程、资源情况--------------
               Max      allocation      Need
进程名         a b c       a b c       a b c
    0          7 5 3       0 1 0       7 4 3
    1          3 2 2       2 0 0       1 2 2
    2          9 0 2       3 0 2       6 0 0
    3          2 2 2       2 1 1       0 1 1
    4          4 3 3       0 0 2       4 3 1
系统可利用资源:  3  3  2
 ---------------------------------------------

请输入一个请求进程的id和请求进程各个资源的量:
1 1 0 2
存在一个安全队列:1->3->0->2->4
分配成功!
--------------当前进程、资源情况--------------
               Max      allocation      Need
进程名         a b c       a b c       a b c
    0          7 5 3       0 1 0       7 4 3
    1          3 2 2       3 0 2       0 2 0
    2          9 0 2       3 0 2       6 0 0
    3          2 2 2       2 1 1       0 1 1
    4          4 3 3       0 0 2       4 3 1
系统可利用资源:  2  3  0
 ---------------------------------------------

请输入一个请求进程的id和请求进程各个资源的量:
4 3 3 0
尚无足够资源,进程须等待

请输入一个请求进程的id和请求进程各个资源的量:
0 2 3 0
不安全,不给分配!

请输入一个请求进程的id和请求进程各个资源的量:

六、结论

银行家算法实现了动态地避免死锁。每次分配试资源后执行安全性算法检测,若存在安全序列系统就是安全的,否则就是不安全会出现死锁并撤销分配。

本文作者:TTMoon

本文链接:https://www.cnblogs.com/shen75/p/18140200

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   TTMoon  阅读(438)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑