操作系统实验之处理机调度

实验要求

  • 选择1~3种进程调度算法(先来先服务、短作业优先、最高响应比优先、时间片轮转、优先级法等)模拟实现进程调度功能;
  • 能够输入进程的基本信息,如进程名、到达时间和运行时间等;
  • 根据选择的调度算法显示进程调度队列;
  • 根据选择的调度算法计算平均周转时间和平均带权周转时间。

我选择了先来先服务FCFS、短作业优先SJF、最高响应比优先HRN、时间片轮转RR四种调度算法,使用java实现。
后面调度算法均用缩写表示。

源码已上传到本人github上,建议先看源码。

实验原理

代码结构

  • Task类用来存放每个任务的详细信息,其私有成员记录任务名字、提交时间运行时间、已运行时间、完成时间、周转时间、带权周转时间,静态私有成员存放平均周转时间、平均带权周转时间以及任务总数。Task类的构造方法需要任务名、到达时间和运行时间。Task类其余方法都是setter和getter。
  • CPU类表示处理机,私有成员包含调度算法、当前时间、时间片长度(RR算法需要用到)任务池、已到达任务池、已到达任务队列(RR算法需要用到)。核心的方法包括四个调度算法以及根据四个调度算法代码中可复用的部分封装出来的代码,比如更新已到达任务池、处理任务、打印时间等等,后续提及时会详细讲解。

代码思路

整体思路

和前面的进程调度不同,处理机调度实现的难点在于确定时间的流动,因为CPU何时会处理某个任务和调度算法有关,而只有知道这个时间才能确定该任务的完成时间,所以CPU类中timeAt用于存放当前时间,在有任务到达或者有任务完成的时候对其进行更新。

CPU类中的任务池和已到达任务池是两个Set,均用HashSet实现;已到达任务队列是Queue,用LinkedList实现。

  • 任务池: 所有任务的集合。每当完成一个任务就从该集合中删掉此任务,当任务池中没有任务则意味着所有任务已完成。
  • 已到达任务池:所有已到达任务的集合。所有已经到达且尚未被执行的任务都在此集合里,故算法调度主要是操作已到达任务池中的任务,每完成一个任务便从该集合中删除掉此任务。
  • 已到达任务队列:和已到达任务池类似,RR调度算法需要一个队列来轮转,每当有任务到达,便从已到达任务池中将任务加到已到达任务队列的队尾。队首的任务会被CPU处理一个时间片,然后出列并放到队尾,直到该任务被处理完毕。

由于各个调度算法中代码可以复用的部分比较多,比如打印时间、填写各个任务的时间等,笔者在重构多次了完成了一些封装,会在后面的算法中具体指出。

FCFS

先来先服务算法向来是被认为是最简单的算法,然而这个调度算法我重构了近三次,因为写到后面才会发现FCFS的思想是其他算法都会用到的,每个调度算法都需要找到最先到达CPU的任务。对于FCFS而言,其过程不过是重复这个过程而已,所以这里代码看起来非常简短,逻辑也很清晰:只要任务池不为空,那就不停的去处理当前第一个到的任务。完成后去设置平均时间然后打印。

    private void FCFS() {
        while (!tasks.isEmpty()) {
            processFirstOne();
        }
        setAvgTime();
        printAvg();
    }

processFirstOne

处理第一个任务又包括找到第一个任务,设置当前时间,处理该任务,从任务池删除该任务以及设置时间和打印时间。不难看到这个方法依然是很多小方法的调用。这里笔者做了比较多的封装来解耦,具体理由可以在后面的调度算法中发现调度算法基本都需要找到处理当前第一个到达的任务,这样做有利于代码复用

关于这里设置当前时间,因为我们不知道当前任务完成后,下一个任务是紧接着就来了还是会隔一段时间才来(即任务与任务之间间隔了一段时间,cpu没有处理任何任务)。所以需要判断下一个任务的到达时间和当前时间哪个更大,如果任务早就到达了,那么当前时间就保持不变即可;反之如果任务到达的比较慢则把当前时间调整为下一个任务的到达时间。

    private void processFirstOne() {
        if (!tasks.isEmpty()) {
            Task chosenOne = findFirstOne();
            this.timeAt = Math.max(this.timeAt, chosenOne.getArriveTime());
            //执行作业
            processingJob(chosenOne);
            tasks.remove(chosenOne);
            setAllTime(chosenOne);
            printAllTime(chosenOne);
        }
    }
  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值