利用银行家算法避免死锁(C语言实现)

利用银行家算法避免死锁

【注】本代码数据及思路方法参考自《计算机操作系统(第四版)》汤小丹等 编著的教材。

#include <iostream>
#define m 3 // 资源数
#define n 5 // 进程数
#define p 3 // 请求资源的进程数

// 可利用资源向量 Available (含有m个元素的数组,每个元素代表一类课利用的资源数目)
int Available[m];
// 最大需求矩阵 Max (n×m的矩阵,n个教程,每个进程对m类资源的最大需求)
int Max[n][m];
// 分配矩阵 Allocation (n×m的矩阵,每类资源当前已分配给每个进程的资源数)
int Allocation[n][m];
// 需求矩阵 Need (n×m的矩阵,每个进程尚需的各类资源数)
int Need[n][m];     // Need[i][j] = Max[i][j] - Allocation[i][j]
// 请求向量
int Request[n];
// 安全序列
int securitySequence[n];

// 初始化函数
void Init()
{
    // 三类资源:A,B,C;资源数量分别为:10, 5, 7
    // 初始时刻资源分配情况
    int a = 0;
    int temp[m * n*3] = {7,5,3,0,1,0,7,4,3,3,2,2,2,0,0,1,2,2,9,0,2,3,0,2,6,0,0,2,2,2,2,1,1,0,1,1,4,3,3,0,0,2,4,3,1};
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            Max[i][j] = temp[a];
            a++;
            //printf("%d", Max[i][j]);
        }
        //printf("\t");
        for (int j = 0; j < m; j++)
        {
            Allocation[i][j] = temp[a];
            a++;
            //printf("%d", Allocation[i][j]);
        }
        //printf("\t");
        for (int j = 0; j < m; j++)
        {
            Need[i][j] = temp[a];
            a++;
            //printf("%d", Need[i][j]);
        }
        //printf("\n");
    }
    Available[0] = 3;
    Available[1] = 3;
    Available[2] = 2;
}

// 安全性检测
bool SafetyCheck()
{
    int index = 0;
    // 1. 设置两个向量,初始化两个向量
    int Work[m];    // 工作向量
    bool Finish[n] = { false };   // 系统是否有足够的资源分配给进程,使之运行完成,默认为没有足够资源
    for (int i = 0; i < m; i++)
        Work[i] = Available[i];
    // 2. 从进程集合中找到一个满足条件的进程(Finish[i] = false; Need[i][j] <= Work[j]),若找到:执行3;否则:执行4
    // 这个循环是错的,应该循环查找,记得改一下!!(可能的问题还是在循环判断这!!!)
    // 安全性检查也有问题,后面的Work有问题,后面的进程判断也有问题!!!
    /*
    (已改)注:在用循环查找到满足两个条件的进程后,继续往后查找,在后面的进程中,找到最后一个也不满足就会产生找不到的假象
    */
    bool findFlag = true;  // 用来标识在一次的for循环中,是否找到了一个满足条件的进程,默认为能找到
    while (findFlag)
    {
        int i;      // 第i个进程
        findFlag = false;   // 在每次的for循环前,设定为找不到满足条件的进程,
                                     // 当找到进程后,再修改成true,作为判断是否再进行一次for查找和判断是否安全的条件
        for (i = 0; i < n; i++)
        {
            if (Finish[i] == false)
            {
                bool flag = true;   // 用来标识是否满足Need[i][j] <= Work[j],默认为满足
                for (int j = 0; j < m; j++)
                {
                    if (Need[i][j] > Work[j])   // 不满足Need[i][j] <= Work[j]
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)   // 该进程满足两个条件
                {
                    // 3. 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源
                    // 输出安全序列的表格(类似于书上的表格)便于检查程序是否正确
                    // if语句没有含义,就是为了在集成开发环境中将输出语句收起来,方便看代码
                    /*if (true)
                    {
                        printf("P%d\t", i);
                        for (int j = 0; j < m; j++)
                            printf("%d", Work[j]);
                        printf("\t");
                        for (int j = 0; j < m; j++)
                            printf("%d", Need[i][j]);
                        printf("\t");
                        for (int j = 0; j < m; j++)
                            printf("%d", Allocation[i][j]);
                        printf("\t");
                        for (int j = 0; j < m; j++)
                            printf("%d", Work[j] + Allocation[i][j]);
                        printf("\n");
                    }*/
                    for (int j = 0; j < m; j++)
                        Work[j] = Work[j] + Allocation[i][j];
                    Finish[i] = true;
                    findFlag = true;
                    securitySequence[index++] = i;
                }
            }
        }
    }
    // 4. 如果所有进程的Finish[i] = true都满足,则系统处于安全状态
    bool safety = true; // 标识系统是否处于安全状态,默认为安全状态
    for (int i = 0; i < n; i++)
    {
        if (Finish[i]==false)    // 存在Finish!=true的进程
        {
            safety = false;     // 系统处于不安全状态
            break;
        }
    }
    if (safety)
        return true;    // true代表安全
    else
        return false;    // false代表不安全
}

// 输出安全序列
void PrintResult()
{
    printf("安全序列为:{");
    for (int i = 0; i < n; i++)
    {
        printf("P%d ",securitySequence[i]);
    }
    printf("}\n");
}

// 银行家算法
int Bankers(int index) 
{// index代表:第index个进程请求资源
    // 1. 如果Request[j]≤Need[i, j] 转向步骤2;否则认为出错:所需资源超过所宣称的最大值
    for (int i = 0; i < m; i++)
    {
        if (Request[i] > Need[index][i])
            return 0;   // 返回0代表:所需资源超过所宣称的最大值
    }
    // 2. 如果Request[j]≤Available[j] 转向步骤3;否则:尚无足够的资源,第index个进程需等待
    for (int i = 0; i < m; i++)
    {
        if (Request[i] > Available[i])
            return 1;   // 返回1代表:尚无足够的资源,进程需等待
    }
    // 3. 系统试着将资源分配给第index个进程,并修改下面数据结构中的数值
    for (int i = 0; i < m; i++)
    {
        Available[i] = Available[i] - Request[i];
        Allocation[index][i] = Allocation[index][i] + Request[i];
        Need[index][i] = Need[index][i] - Request[i];
    }
    // 4. 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全:完成分配;否则:取消分配
    if (SafetyCheck())  // 当SafetyCheck()返回true时:表明安全
    {
        return 2;   // 返回2代表:完成分配
    }
    else
    {
        for (int i = 0; i < m; i++)     // 取消分配,恢复原来的资源分配状态
        {
            Available[i] = Available[i] + Request[i];
            Allocation[index][i] = Allocation[index][i] - Request[i];
            Need[index][i] = Need[index][i] + Request[i];
        }
        return 3;   // 返回3代表:完成分配后,系统将处于不安全的状态
    }
}

int main()
{
    Init();
    int tempRequest[p][m] = { { 1, 0, 2 }, {3,3,0}, {0, 2, 0} };    // 各进程的对应请求资源数
    int process[p] = { 1, 4, 0 };   // 请求资源的进程号:P1 -> P4 -> P0
    
    for (int i = 0; i < p; i++)
    {
        for (int j = 0; j < m; j++) // 赋值资源请求数目
        {
            Request[j] = tempRequest[i][j];
        }
        int result = Bankers(process[i]);

        if (result == 0)
        {
            printf("所需资源超过所宣称的最大值\n");
        }
        else if (result == 1)
        {
            printf("尚无足够的资源,进程需等待\n");
        }
        else if (result == 2)
        {
            PrintResult();
        }
        else if (result == 3)
        {
            printf("完成分配后,系统将处于不安全的状态(取消分配)");
        }
    }
}

  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
银行家算法是一种操作系统中用于避免死锁的算法。它通过动态地分配资源来避免死锁的发生。在银行家算法中,系统会对每个进程的资源请求进行检查,如果该请求导致系统进入不安全状态,则该请求将被拒绝,否则该请求将被满足。C语言是一种常用的编程语言,可以用来实现银行家算法。 以下是利用C语言实现银行家算法的基本步骤: 1. 定义进程数和资源数,以及每个进程的最大需求量、已分配资源量和需要资源量。 2. 定义可用资源量和安全序列。 3. 实现银行家算法的主要函数,包括安全性检查函数和资源分配函数。 4. 在主函数中调用银行家算法函数,输出安全序列或死锁信息。 以下是一个简单的C语言实现银行家算法的例子: ```c #include <stdio.h> #define MAX_PROCESS 10 #define MAX_RESOURCE 10 int available[MAX_RESOURCE]; int max[MAX_PROCESS][MAX_RESOURCE]; int allocation[MAX_PROCESS][MAX_RESOURCE]; int need[MAX_PROCESS][MAX_RESOURCE]; int work[MAX_RESOURCE]; int finish[MAX_PROCESS]; int safety_check(int n, int m) { int i, j, k, count = 0; for (i = 0; i < m; i++) { work[i] = available[i]; } for (i = 0; i < n; i++) { finish[i] = 0; } while (count < n) { int found = 0; for (i = 0; i < n; i++) { if (!finish[i]) { int flag = 1; for (j = 0; j < m; j++) { if (need[i][j] > work[j]) { flag = 0; break; } } if (flag) { for (k = 0; k < m; k++) { work[k] += allocation[i][k]; } finish[i] = 1; found = 1; count++; } } } if (!found) { return 0; } } return 1; } int resource_request(int pid, int request[], int n, int m) { int i, j; for (i = 0; i < m; i++) { if (request[i] > need[pid][i] || request[i] > available[i]) { return 0; } } for (i = 0; i < m; i++) { available[i] -= request[i]; allocation[pid][i] += request[i]; need[pid][i] -= request[i]; } if (!safety_check(n, m)) { for (i = 0; i < m; i++) { available[i] += request[i]; allocation[pid][i] -= request[i]; need[pid][i] += request[i]; } return 0; } return 1; } int main() { int n, m, i, j; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the number of resources: "); scanf("%d", &m); printf("Enter the available resources: "); for (i = 0; i < m; i++) { scanf("%d", &available[i]); } printf("Enter the maximum demand of each process: "); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { scanf("%d", &max[i][j]); } } printf("Enter the allocated resources of each process: "); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { scanf("%d", &allocation[i][j]); need[i][j] = max[i][j] - allocation[i][j]; } } if (safety_check(n, m)) { printf("The system is in safe state.\n"); } else { printf("The system is in unsafe state.\n"); } int pid; int request[MAX_RESOURCE]; printf("Enter the process id and resource request: "); scanf("%d", &pid); for (i = 0; i < m; i++) { scanf("%d", &request[i]); } if (resource_request(pid, request, n, m)) { printf("The request is granted.\n"); } else { printf("The request is denied.\n"); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值