在C语言中使用银行家算法预防死锁

C语言中使用银行家算法预防死锁

什么是死锁

死锁是指在一个并发系统中,两个或以上的线程互相等待对方的资源而无限制地等待下去,使得进程无法继续运行而陷入一种“死循环”,形成死锁。

银行家算法

银行家算法是一种避免死锁的算法。它通过动态地分配资源,避免进程因竞争资源而发生死锁,并保证分配的资源不会导致系统不安全。

银行家算法的实现需要考虑以下信息:

  • Available:当前可用的资源数目。
  • Max:系统中每种资源的最大需求量。
  • Allocation:系统中每种资源当前已分配的数量。
  • Need:系统中每种资源还需要的数量。

死锁避免的步骤

使用银行家算法避免死锁可以分为以下步骤:

  1. 初始化资源可用数量 Available,系统的所有进程以及它们的资源需求量 Max 和已分配资源数量 Allocation。
  2. 检查系统是否处于安全状态,也就是系统是否有足够的资源满足后续进程的请求。如果是,则接受请求并更新资源分配情况;否则,拒绝请求,等待其他进程释放资源。
  3. 继续进行死锁预防工作。每当分配或释放资源时,都要重新计算实际可用资源和各个进程还需要的资源数量,并尝试将之前因拒绝请求而被阻塞的进程重新考虑分配资源。

示例1:使用银行家算法避免死锁

假设系统中有5个进程,申请资源的顺序为 P1、P2、P3、P4、P5。分别显示它们对三类资源的最大需求量 Max 和已分配资源数量 Allocation 如下表所示。

进程 Allocation Max Need
P1 1 1 0 2 1 1 1 0 1 (Max-Allo)
P2 1 0 1 2 1 2 1 1 1
P3 1 0 0 1 2 0 0 2 0
P4 0 0 1 3 0 0 3 0 2
P5 0 0 1 2 0 1 2 0 0

此时可用资源数量 Available 为 1 2 0。

假设现在进程 P4 申请 1 0 0 资源,判断如下:

  1. 检查系统是否处于安全状态,此时 Available 与 Need 比较结果如下:
进程 Need Available Work Finish
P1 1 0 1 0 2 0 0 0 0 No
P2 1 1 0
P3 0 2 0
P4 3 0 2
P5 2 0 0

则 P2 或 P3 可以被分配资源,我们选择 P2,分配资源后,状态如下:

进程 Allocation Need Available Work Finish
P1 1 0 1 1 0 0 0 1 0 1 0 0 No
P2 1 1 1 1 0 1 1 1 0 0 1 0 Yes
P3 1 0 0 0 2 0 1 2 1 0 0 0 No
P4 0 0 1 3 0 1 1 2 1 0 0 1 No
P5 0 0 1 2 0 0 1 2 2 0 0 0 No
  1. P4 的申请可以被满足,并更新 Allocation 和 Available 信息,状态如下:
进程 Allocation Max Need
P1 1 0 1 2 1 1 1 1 0
P2 1 1 1 2 1 2 1 0 1
P3 1 0 0 1 2 0 0 2 0
P4 0 0 2 3 0 0 3 0 0
P5 0 0 1 2 0 1 2 0 0
1 1 4 10 5 8 5 3 9 (Max-Allo)
  1. 继续进行死锁预防工作,更新各个进程需要的资源数量,状态如下:
进程 Allocation Max Need
P1 1 0 1 2 1 1 1 1 0
P2 1 1 1 2 1 2 1 0 1
P3 1 0 0 1 2 0 0 2 0
P4 0 0 2 3 0 0 3 0 0
P5 0 0 1 2 0 1 2 0 0

示例2:配合源代码使用银行家算法避免死锁

下面是一个基于 C 语言的简单死锁避免示例代码,使用了银行家算法的思想。它让两个线程按不同的顺序执行,增加了产生死锁的概率,验证了死锁验证的正确性。

#include<stdio.h>
#include<stdlib.h>

int available[10],max[10][10],allocation[10][10],need[10][10],flag[10],work[10];
int num_process,num_res;

int input_data() {
    int i,j;
    printf("Enter the number of processes: ");
    scanf("%d",&num_process);
    printf("Enter the number of types of resources: ");
    scanf("%d",&num_res);
    for(i=1;i<=num_process;i++){
        printf("Enter the allocation of process %d: ",i);
        for(j=1;j<=num_res;j++){
            scanf("%d",&allocation[i][j]);
        }
        flag[i]=0;
    }
    printf("\n");
    for(i=1;i<=num_process;i++){
        printf("\nEnter the Max Matrix for process %d : ",i);
        for(j=1;j<=num_res;j++){
            scanf("%d",&max[i][j]);
        }
    }
    printf("\n");
    printf("\nEnter the Available Resources : ");
    for(i=1;i<=num_res;i++){
        scanf("%d",&available[i]);
        work[i]=available[i];
    }
    printf("\n");
    return 0;
}

void calculate_need(){
    int i,j;
    for(i=1;i<=num_process;i++){
        for(j=1;j<=num_res;j++){
            need[i][j]=max[i][j]-allocation[i][j];
        }
    }
}

int check_availability(int j){
    int i;
    for(i=1;i<=num_res;i++){
        if (need[j][i]>work[i]){
            return 0;
        }
    }
    return 1;
}

int wait_or_exit(){
    int i,j,found,flag;
    for(i=1;i<=num_process;i++){
        if(flag[i]==0 && check_availability(i)){
            flag[i]=1;
            for(j=1;j<=num_res;j++){
                work[j]=work[j]+allocation[i][j];
            }
            break;
        }
    }
    if(i>num_process){
        return 0;
    }
    else{
        return 1;
    }
}

void detect_deadlock(){
    int i,j,found,flag;
    calculate_need();
    int process_allocated = 0;
    while(process_allocated<num_process){
        found = 0;
        for(i=1;i<=num_process;i++){
            if(flag[i]==0 && check_availability(i)){
                flag[i]=1;
                found = 1;
                printf("\nProcess %d is allocated resources ",i);
                for(j=1;j<=num_res;j++){
                    work[j]=work[j]+allocation[i][j];
                }
                process_allocated++;
            }
        }
        if(found==0){
            printf("\nSystem is not in safe state\n");
            return;
        }
    }
    printf("\nSystem is in safe state\n");
}

int main(){
    input_data();
    detect_deadlock();
    return 0;
}

这个代码输入了最大需求量、当前已分配数量和可用资源数量。它先计算出需要的资源数量,然后检查系统是否处于安全状态。如果不是,就需要等待其他资源释放。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:在C语言中使用银行家算法预防死锁 - Python技术站

(0)
上一篇 2023年5月9日
下一篇 2023年5月9日

相关文章

  • C语言预编译#define(预处理)

    C语言预处理#define的完整攻略 什么是C语言预处理 C语言预处理是在编译阶段之前进行的一些预处理操作,包括文件包含、宏定义、条件编译等等。其中,宏定义是其中最为常见的预处理操作,它使用预处理指令#define来定义一个标识符,以便在代码中进行替换。 预处理指令#define的语法 预处理指令#define的语法如下: #define 标识符 替换文本 …

    C 2023年5月23日
    00
  • 如何通过UltraEdit解析BMP文件内部结构(BMP位图基础)

    下面我将详细讲解如何通过UltraEdit解析BMP文件内部结构。 准备工作 下载安装UltraEdit 准备一张BMP格式的图片 解析过程 打开UltraEdit软件 打开BMP文件:文件 > 打开 打开文件后,将光标移至字节流数据处,右键点击选择Hex/ASCII菜单,然后点击设置’#’注释符。 在弹出的对话框中,选择无作为注释符,点击确定按钮。 …

    C 2023年5月23日
    00
  • c语言处理函数调用的方法

    C语言中处理函数调用的方法是程序设计中非常基础和重要的知识。以下是处理函数调用的方法的完整攻略,包括两个示例: 函数调用方法 在C语言中,函数通常被定义在程序的顶部,并在需要的时候被调用。函数调用是通过函数名、左括号、函数参数、右括号来完成的。下面是函数调用的基本语法: function_name(arguments); 在上面的语法中,function_n…

    C 2023年5月23日
    00
  • Ruby中Time对象的常用函数总结

    Ruby中Time对象的常用函数总结 Ruby中Time对象是一个表示时间的类,它提供了一系列常用的函数来方便处理时间相关的操作。在本文中,我们将为大家总结一下Ruby中Time对象的常用函数及其用途。 获取当前时间 我们可以使用Time.now函数来获取当前时间。 current_time = Time.now puts current_time 输出结果…

    C 2023年5月23日
    00
  • C语言如何建立动态链表问题

    建立动态链表是C语言中常见的数据结构应用之一。以下是如何建立动态链表的完整攻略: 步骤一:定义链表结构 首先需要定义一个链表结构体,包括节点数据和指向下一个节点的指针。 typedef struct Node { int data; struct Node *next; } Node; 步骤二:创建头结点 链表的头结点是链表的入口,不存储数据,只存储链表中第…

    C 2023年5月23日
    00
  • C语言实现的学生选课系统代码分享

    C语言实现的学生选课系统代码分享 简介 本文将分享一份用C语言实现的学生选课系统代码,该系统实现了学生的选课、退课、成绩查看等功能。通过学习本系统的代码,可以加深对C语法及数据结构的理解。 功能模块 学生选课系统包含了以下几个功能模块: 学生信息管理 课程信息管理 学生选课 学生退课 成绩查询 数据结构 该系统使用了以下数据结构: 结构体:用于存储学生信息、…

    C 2023年5月23日
    00
  • C语言利用sprintf固定字符串输出位数

    C语言中常用的输出函数是printf,该函数可以输出各种类型的数据,但是无法固定输出的长度。如果想要输出固定长度的字符串,可以使用sprintf函数。本文将详细讲解sprintf固定字符串输出位数的攻略。 sprintf函数概述 sprintf是C语言中的输出函数,其原型为: int sprintf(char *str, const char *format…

    C 2023年5月22日
    00
  • springboot解决java.lang.ArrayStoreException异常

    当我们在使用Spring Boot时,有时候会遇到java.lang.ArrayStoreException异常,这是因为在编译期间未正确识别数组类型,导致在运行期间出现异常。下面我将介绍如何解决这个问题的完整攻略。 1. 理解java.lang.ArrayStoreException异常是什么 java.lang.ArrayStoreException异常…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部