银行家算法是如何实现的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了银行家算法是如何实现的?相关的知识,希望对你有一定的参考价值。

银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。

�7�4 与预防死锁的几种方法相比较,限制条件少,资源利用程度提高了。

�7�4 缺点:该算法要求客户数保持固定不变,这在多道程序系统中是难以做到的;该算法保证所有客户在有限的时间内得到满足,但实时客户要求快速响应,所以要考虑这个因素;由于要寻找一个安全序列,实际上增加了系统的开销.

Banker algorithm 最重要的一点是:保证操作系统的安全状态!这也是操作系统判断是否分配给一个进程资源的标准!那什么是安全状态?举个小例子,进程 P 需要申请 8 个资源(假设都是一样的),已经申请了 5 个资源,还差 3 个资源。若这个时候操作系统还剩下 2 个资源。很显然,这个时候操作系统无论如何都不能再分配资源给进程 P 了,因为即使全部给了他也不够,还很可能会造成死锁。若这个时候操作系统还有 3 个资源,无论 P 这一次申请几个资源,操作系统都可以满足他,因为操作系统可以保证 P 不死锁,只要他不把剩余的资源分配给别人,进程 P 就一定能顺利完成任务。 为什么银行家算法是可行的呢?这里需要严格的证明一下。不管任何时候,操作系统分配资源的时候都可以保证当前接受资源的进程不会陷入死锁,因为操作系统总是可以满足该进程需要的资源的。假设有 n 个进程 p1, p2, p3, … pn ,最后一个分配到资源的是 pi , pi 还需要 mi 个资源,假设此时操作系统还有 m 个资源剩余。那么很显然 m>=mi !而且如果之后操作系统又把资源分配给其他进程了,假设是 pj , pj 还需要 mj 个资源,同理可知 m>=mj !也就是说在所有的进程中,还需要的资源数总是有小于 m 的!这样就可以保证资源数永远不会为 0 ,即使可能暂时性为 0 。另外,还需要保证资源数不会减少!而且,所有已经分配到资源的进程总有一天会归还它所拥有的资源!根据操作系统再分配的时候的状态即可判定。
参考技术A #include "string.h"
#include <stdio.h>
#include <stdlib.h>
#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<0||i>=M)

printf("请输入需申请资源的进程号(从0到");
printf("%d",M-1);
printf(",否则重输入!):");
scanf("%d",&i);
if(i<0||i>=M)printf("输入的进程号不存在,重新输入!\n");

printf("请输入进程");
printf("%d",i);
printf("申请的资源数\n");
for (j=0;j<N;j++)

printf("资源");
printf("%d",j);
printf(":");
scanf("%d",&Request[j]);
if(Request[j]>NEED[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<M;i++)
printf("进程");
printf("%d",temp[i]);
printf("->");

printf("\n");
return 0;
参考技术B 银行家算法不是单说就行的,如果真想弄明白最好看看 操作系统 这本书! 参考技术C 编制银行家算法通用程序,并检测所给状态的系统安全性。
1)银行家算法中的数据结构:
可利用资源向量Available。这是一个含有m个 元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。Available[j]=K,则表示系统中现有Rj 类资源K个。
最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源 当前已分配给没一进程的资源数。如果Allocation[i,j]=K,则表示 进程i当前已分得Rj类资源的数目为K。
需求矩阵Need。这也是一个n*m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。
上述三个矩阵存在如下关系:
Need[i,j]= Max[i,j]- Allocation[i,j]
2)银行家算法
设Request[i] 是进程Pi的请求向量,如果Request[i,j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
如果Request[i,j]<= Need[i,j],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。

计算机操作系统 --- 共享资源分配与银行家算法java篇

大家好!我是小笙,最近一周我们进行课程设计的制作,以下是我分享的源码!


课程设计的要求

此次课程设计的主要内容是模拟实现资源分配。同时要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并使用适当的算法,有效的防止和避免死锁的发生。
具体用银行家算法实现资源分配。
要求如下:
1.设计一个5个并发进程共享3类不同资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。(也可以超过5个进程,3类资源)
2.设计用银行家算法和随机分配算法,实现资源分配的两个资源分配程序,应具有显示或打印各进程依次要求申请的资源数以及依次分配资源的情况。
3.确定一组各进程依次申请资源数的序列,在相同的情况下分别运行上述两种资源分配程序,观察运行结果。
笙式解读(代码实现):
1.可以手动一个一个进程的方式输入资源,进程数以及资源种类数都是可以我们自己设置
2.分别实现银行家算法和随机分配算法

银行家算法的分配资源是:当某个进程提出资源申请时,假定先分配资源给它,然后查找各进程的剩余请求,检查系统剩余资源量是否由于进程的分配而导致系统死锁。若能,则让进程等待,否则,让进程的假分配变为真分配。
随机分配算法的分配原则:当进程申请资源时,如果进程现有资源数能满足进程的当前申请量,就把资源分配给进程,否则,让其等待。这样,随机算法可能引起死锁。

3.安全性算法的实现输出序列

主菜单

// 启动类
public class Application 
    public static void main(String[] args) throws IOException 
        new CoreProcessor();
    

主菜单运行效果

// 主菜单的代码
    public CoreProcessor() throws IOException 
        while(true)
            System.out.println("*******************************");
            System.out.println("       共享资源分配与银行家算法     ");
            System.out.println("       1.系统资源分配信息          ");
            System.out.println("       2.添加进程及进程信息         ");
            System.out.println("       3.删除进程及进程信息        ");
            System.out.println("       4.查找进程及进程信息       ");
            System.out.println("       5.检查是否序列安全        ");
            System.out.println("       6.提出请求资源          ");
            System.out.println("       7.读入文件数据          ");
            System.out.println("       8.保存文件数据          ");
            System.out.println("       9.清除进程和资源信息    ");
            System.out.println("       10.退出系统            ");
            System.out.println("*******************************");
            System.out.print("输入序号(1~10):");

            // 序号必须在1~10之间
            int choice = new Scanner(System.in).nextInt();
            if(!(choice <=10 && choice>=1))
                continue;
            

            switch (choice)
                case 1: SystemResourceInformation();
                        break;
                case 2: AddProcessesAndProcessInformation();
                        break;
                case 3: DeleteProcessesAndProcessInformation();
                        break;
                case 4: SearchForProcessesAndProcessInformation(head);
                        break;
                case 5: IsSafety();
                        break;
                case 6: AskForRequest();
                        break;
                case 7: ReadFile();
                        break;
                case 8: SaveFile();
                        break;
                case 9: ClearProcessAndResourceInformation();
                        break;
                case 10: ExitSystem();
                        break;
                default:
                    System.out.println("impossible");
            
        
    

主要函数说明

添加进程

笙式说明:
我实现两种添加进程的方式
1.手动一个进程一个进程输入(麻烦)
2.直接文件读入(方便快捷)

1.手动输入进程

做任何操作前,我们都需要先完成系统资源信息录入
录入内容为:系统资源种类数 && 可分配资源数(available)

如果我们输入错误如何更改呢?
我们可以通过主菜单的9序号清空系统资源数据

// 9.清除进程和资源信息
    private void ClearProcessAndResourceInformation()
        numberOfResourcTypes = 0;
        head.next = null;
    

接下类就是CRUD的操作,不需要我多说叭!
我操作一下添加进程

 // 2.添加进程及进程信息
    private void AddProcessesAndProcessInformation()
        if(numberOfResourcTypes == 0)
            System.out.println("系统资源分配信息未输入!!!");
            SystemResourceInformation();
        
        while (true)
            System.out.println("*******************************");
            System.out.println("       添加进程及进程信息     ");
            System.out.println("       1.添加进程          ");
            System.out.println("       2.退出          ");
            System.out.print("输入序号(1~2):");
            // 序号必须在1~2之间
            int choice = new Scanner(System.in).nextInt();
            if(choice == 2)
                System.out.println("添加进程完成!");
                System.out.println("*******************************");
                return;
            
            if(!(choice <=2 && choice>=1))
                System.out.println("*******************************");
                continue;
            

            // 开始添加进程信息
            // processName
            System.out.print("\\n输入进程名:");
            String processName = new Scanner(System.in).next().trim();
            // Max
            System.out.print("输入"+numberOfResourcTypes+"个最大需求资源数(max):");
            int[] max = new int[numberOfResourcTypes];
            Scanner sc = new Scanner(System.in);
            for (int i = 0; i < max.length; i++) 
                max[i] = sc.nextInt();
            
            // Allocation Need
            System.out.print("输入"+numberOfResourcTypes+"个已分配资源数(allocation):");
            int[] allocation = new int[numberOfResourcTypes];
            int[] need = new int[numberOfResourcTypes];
            for (int i = 0; i < numberOfResourcTypes; i++) 
                allocation[i] = sc.nextInt();
                need[i] = max[i] - allocation[i];
            
            // 检验是否出错 及其进程名有无重复
            if(IsSameName(processName))
                System.out.println("进程名重复了,请重新输入");
                continue;
            
            for (int i = 0; i < numberOfResourcTypes; i++) 
                if(max[i]<0 || allocation[i]<0 || need[i]<0)
                    System.out.println("进程数据有误,返回核心处理器!!!");
                    return;
                
            

            // 添加新进程到新链表
            Process temp = head;
            // 遍历链表,找到最后
            while(true)
                if(temp.next == null)
                    break;
                
                temp = temp.next;
            
            // 当退出while循环时候,temp就指向最后一个节点
            temp.next = new Process(processName,max,allocation,need);

            // 提示进程是否安全
            // IsSafety();
            System.out.println();
            System.out.println("*******************************");
        
    

既然添加了两个进程,此时我想看看这两个进程了怎么办?放心没问题

2.直接文件读入

读入的文本说明

读入的实现效果

读入的代码实现

// 7.读入文件数据
public void ReadFile() 
    if(numberOfResourcTypes != 0)
        System.out.println("系统资源分配信息已经输入!!!");
        return;
    
    List input = new ArrayList();
    System.out.println("请问你要读入文件的文件名:");
    String s = new Scanner(System.in).next();
    String pathname = "E:\\\\enableCleanProject\\\\SharedResourceAllocationAndBankerAlgorithm\\\\OSAlgorithm\\\\src\\\\" + s;
    try (FileReader reader = new FileReader(pathname);BufferedReader br = new BufferedReader(reader)) 
        String line;
        while ((line = br.readLine()) != null) 
            // 一次读入一行数据
            String[] str =line.split(" ");
            input.add(str[0]);
        
     catch (IOException e) 
        e.printStackTrace();
    
    numberOfResourcTypes =  Integer.valueOf(input.get(0).toString());
    String processName = "";
    Available = new int[numberOfResourcTypes];
    for (int i = 1; i <= numberOfResourcTypes; i++) 
        Available[i-1] = Integer.valueOf(input.get(i).toString());
    
    int count = (input.size()-(1+numberOfResourcTypes))/(numberOfResourcTypes*3+1);
    int[][] max = new int[count][numberOfResourcTypes];
    int[][] allocation = new int[count][numberOfResourcTypes];
    int[][] need = new int[count][numberOfResourcTypes];

    // 添加新进程到新链表
    Process temp = head;
    while(count > 0)
        processName = input.get((1+numberOfResourcTypes)+(5-count)*(numberOfResourcTypes*3+1)).toString();
        int num =(1+numberOfResourcTypes)+(5-count)*(numberOfResourcTypes*3+1);
        int index = 0;
        for (int i = num+1; i <= num+numberOfResourcTypes; i++) 
            max[5-count][index] = Integer.valueOf(input.get(i).toString());
            index++;
        
        index = 0;
        for (int i = num+1+numberOfResourcTypes; i <= num+numberOfResourcTypes*2; i++) 
            allocation[5-count][index] = Integer.valueOf(input.get(i).toString());
            index++;
        
        index = 0;
        for (int i = num+1+numberOfResourcTypes*2; i <= num+numberOfResourcTypes*3; i++) 
            need[5-count][index] = Integer.valueOf(input.get(i).toString());
            index++;
        
        temp.next = new Process(processName,max[5-count],allocation[5-count],need[5-count]);
        temp = temp.next;
        count--;
    
    System.out.println("读入成功");

好啦!结束了进程录入,上主角三种算法:安全性算法,银行家算法,随机分配算法

算法实现

安全性算法

// 5.检查是否序列安全
    private boolean IsSafety()
        if(numberOfResourcTypes == 0)
            System.out.println("系统资源分配信息未输入!!!");
            SystemResourceInformation();
        
        // 判断进程链表是否为空
        if(head.next == null)
            return true;
        

        // 初始化参数 将一维数组 ==> 二维数组
        int index = 0; // 记录下标
        int[][] allocation = new int[processLength()][numberOfResourcTypes];
        int[][] need = new int[processLength()][numberOfResourcTypes];
        String[] processName = new String[processLength()];

        Process temp = head;
        while(true)
            if(temp.next == null)
                break;
            
            processName[index] = temp.next.getName();
            allocation[index] = temp.next.getAllocationResource();
            need[index] = temp.next.getNeedResource();
            index++;
            temp = temp.next;
        
        // 结束标志
        int end = processLength()-1;
        int numIndex = 0; // 记录顺序下标
        int以上是关于银行家算法是如何实现的?的主要内容,如果未能解决你的问题,请参考以下文章

银行家算法 C语言编程

C语言实现的操作系统银行家算法

银行家算法-C语言实现

C程序模拟实现银行家算法

模拟实现银行家调度算法

银行家算法的python代码实现,感觉python写算法简直要起飞