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

Posted Al_tair

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机操作系统 --- 共享资源分配与银行家算法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以上是关于计算机操作系统 --- 共享资源分配与银行家算法java篇的主要内容,如果未能解决你的问题,请参考以下文章

操作系统之银行家算法避免死锁

操作系统——银行家算法(java实现)

C#窗体模拟银行家算法

银行家算法实例|操作系统

怎么处理JAVA多线程死锁问题?

操作系统实验四 银行家算法