详解操作系统四大常用的作业调度算法(FCFS丨SJF丨HRRN丨RR)

先来先服务调度算法(FCFS)

先来先服务调度算法(First-Come, First-Served, FCFS)是一种基本的进程调度算法,其核心思想是按照作业到达时间的先后顺序进行调度。

FCFS调度算法的工作过程如下:

  1. 当一个作业到达时,将其放入就绪队列的末尾。
  2. 当前执行的作业执行完毕后,从就绪队列中选择队首的作业进行运行。
  3. 重复步骤2,直到所有作业都执行完毕。

FCFS调度算法的优点是实现简单,公平性较好。由于按照作业到达的先后顺序进行调度,所以所有作业都可以得到执行,不存在作业“饥饿”问题。

然而,FCFS调度算法也存在一些缺点。首先,如果有一个长作业在队首,那么后面的作业就必须等待很长时间才能得到执行,导致平均等待时间较长。而且,FCFS调度算法无法适应作业的不同执行时间,执行时间较长的作业会导致整个系统的响应时间变长。

总结来说,FCFS调度算法是一种简单易实现的调度算法,公平性较好。但在实际应用中,需要注意长作业的等待时间较长的问题。

样例1:

有三个作业按下表的时间提交给系统,请按照先来先服务的调度算法计算它们的平均周转时间T和平均带权周转时间W

作业号提交时刻作业长度
110:002小时
210:061小时
310:150.25小时

分析:按照先来先服务的原则,可以计算出各个作业在系统中的开始执行时刻、结束时刻、周转时间。为了一目了然,我们可以在给定表的基础上增加四个新的列:开始执行时刻、结束时刻、周转时间、带权周转时间

周转时间 = 作业结束时刻 - 作业提交时刻
带权周转时间 = 周转时间 / 作业长度

作业号提交时刻作业长度开始时刻结束时刻周转时间带权周转时间
110:002小时10:0012:0021
210:061小时12:0013:002.92.9
310:150.25小时13:0013:15312

三个作业的平均周转时间T和平均带权周转时间W为:

T =(2.00+2.90+3.00)/ 3 = 2.63(小时)
W =(1+2.9+12)/ 3 = 5.30(小时)

短作业优先调度算法(SJF)

短作业优先调度算法是一种常见的进程调度算法,其核心思想是优先执行执行时间较短的作业。短作业指的是估计执行时间短的作业,也可以理解为剩余执行时间短的作业。

短作业优先调度算法的工作过程如下:

  1. 首先,按照作业的执行时间对待执行的作业队列进行排序,即将估计执行时间较短的作业排在前面。
  2. 然后,选择执行时间最短的作业来运行,直到该作业执行完毕或者被阻塞。
  3. 当作业执行完毕或者被阻塞时,从待执行作业队列中选择下一个执行时间最短的作业来运行。
  4. 重复步骤2和步骤3,直到所有作业都执行完毕。

短作业优先调度算法的优点是可以最大程度地减少平均等待时间,使得作业能够快速执行完毕。然而,该算法可能会导致长作业等待时间过长,造成长作业的“饥饿”现象。

总结来说,短作业优先调度算法是一种简单高效的调度算法,适用于执行时间短的作业,并能够减少平均等待时间。但在实际应用中需要注意长作业的“饥饿”问题。

样例2:

还是上面的例子,请按短作业优先算法计算它们的平均周转时间和平均带权周转时间

作业号提交时刻作业长度
110:002小时
210:061小时
310:150.25小时

分析:为了运算方便,在上面作业表的基础上增加五个新的列:调度次序、开始执行时刻、结束时刻、周转时间,以及带权周转时间,从而得到下面的表:

作业号提交时刻作业长度调度次序开始时刻结束时刻周转时间带权周转时间
110:002小时110:0012:0021
210:061小时312:1513:153.13.1
310:150.25小时212:0012:1528

三个作业的平均周转时间T和平均带权周转时间W为:

T =(2.00+3.10+2.00)/ 3 = 2.37(小时)
W =(1+2.9+12)/ 3 = 4.03(小时)

高响应比优先调度算法(HRRN)

高响应比优先调度算法(High Response Ratio Next, HRRN)是一种动态优先级的进程调度算法,其核心思想是根据作业的响应比来确定执行顺序。

HRRN调度算法的工作过程如下:

  1. 当一个作业到达时,计算其响应比。响应比定义为作业等待时间加上作业执行时间除以作业执行时间,即 (等待时间 + 作业长度) / 作业长度。
  2. 将计算得到的响应比最高的作业放入就绪队列。
  3. 当前执行的作业执行完毕后,从就绪队列中选择响应比最高的作业进行运行。
  4. 重复步骤2和步骤3,直到所有作业都执行完毕。

HRRN调度算法的优点是能够根据作业的等待时间和执行时间动态调整优先级,使得等待时间较长的作业能够优先得到执行,提高系统的响应速度。

然而,HRRN调度算法也存在一些缺点。首先,计算响应比需要动态获取作业的等待时间和执行时间,增加了系统的开销。此外,如果作业的执行时间很短,那么响应比会很高,导致其他作业长时间等待,可能会出现“长作业优先”问题。

总结来说,HRRN调度算法是一种具有动态优先级的调度算法,能够提高系统的响应速度。但需要注意计算响应比的开销以及长作业优先问题。

样例3:

表中有4个作业提交给系统,按响应比高者优先算法调度,计算它们的平均周转时间和平均带权周转时间

作业号提交时刻运行长度
18:002小时
28:300.5小时
39:000.1小时
49:300.2小时

分析:为了计算方便,同样在表中增加五个新列:调度次序、开始执行时刻、结束时刻、周转时间,以及带权周转时间

先画出一个表格,后五列是空的,等待我们填入数据:

作业号提交时刻运行长度调度次序开始时刻结束时刻周转时间带权周转时间
18:002小时
28:300.5小时
39:000.1小时
49:300.2小时

作业1做完后,其它三个作业的响应比为:
R2p = 1 + 已等待时间/作业长度 = 1 + 1.5/0.5 = 4
R3p = 1 + 1.0/0.1 = 11
R4p = 1 + 0.5/0.2 = 3.5
故作业3的响应比最大,作业1完成后要运行作业3。

作业3运行结束时,时间为10:06,这时候再看作业2、4的响应比哪个高:
R2p = 1 + 已等待时间/作业长度 =1 + 1.6/0.5 = 4.2
R4p = 1 + 0.6/0.2 = 4
R2p > R4p 所以先调度作业2到内存中,作业2运行完毕,结束时间为:10:36,最后调入作业4到内存。即作业调度的次序为:作业1、作业3、 作业2、 作业4

作业号提交时刻运行长度调度次序开始时刻结束时刻周转时间带权周转时间
18:002小时18:0010:0021
28:300.5小时310:0610:362.14.2
39:000.1小时210:0010:061.111
49:300.2小时410:3610:481.36.5

根据上面的表,可计算出4个作业的平均周转时间T和平均带权周转时间W为:

T =(2+2.1+1.1+1.3)/ 4 = 1.625(小时)
W =(1+4.2+11+6.5)/ 4 = 5.675(小时)

时间片轮转调度算法(RR)

时间片轮转调度算法(Round Robin Scheduling)是一种基于时间片的进程调度算法,旨在公平地分配CPU时间给各个就绪进程。

时间片轮转调度算法的工作过程如下:

  1. 将所有就绪进程按照到达时间的顺序放入就绪队列。
  2. 设定一个固定的时间片大小,通常为几十毫秒。
  3. 从就绪队列中选择一个进程,分配给它一个时间片的CPU时间。
  4. 若该进程在时间片结束前完成任务,则该进程被移出就绪队列,否则将其放到队列的末尾等待下一次调度。
  5. 重复步骤3和步骤4,直到所有进程执行完毕。

时间片轮转调度算法的优点是能够公平地分配CPU时间给每个就绪进程,避免某个进程独占CPU资源,从而提高系统的可响应性和吞吐量。

然而,时间片轮转调度算法也存在一些缺点。首先,如果时间片太短,频繁进行上下文切换会带来较大的开销。另外,如果某些进程的执行时间较长,会导致其他进程长时间等待,可能会出现“长作业效应”问题。

总结来说,时间片轮转调度算法是一种能够公平分配CPU时间的调度算法,适用于多道程序环境。但需要注意时间片大小的设置以及长作业效应问题。

样例4:

5个进程P1、P2、P3、P4、P5几乎同时到达,预期运行时间分别为10、6、2、4、8个时间单位。请按时间片轮转调度算法计算任务的平均周转时间(假定时间片大小为2个时间单位)。

分析:

按顺序运行5个进程

进程号P1P2P3P4P5备注
剩余运行时间106248
第一趟246810P3运行完
剩余运行时间84026
第二趟12141618P4运行完
剩余运行时间62004
第三趟2022024P2运行完
剩余运行时间40002
第四趟2628P5运行完
剩余运行时间20000
第四趟30P1运行完

时间片轮转调度顺序:
顺序

平均值
周转时间101618223019.2
带权周转时间12.6795.53.754.384
  • 22
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
操作系统中的进程调度算法有很多,其中比较常见的有FCFS(先来先服务)、SJF(短作业优先)和RR(时间片轮转)等。下面分别介绍这三种调度算法的Java实现。 1. FCFS算法实现 FCFS算法即先来先服务,按照进程到达的顺序进行调度。 ``` import java.util.LinkedList; import java.util.Queue; public class FCFS { public static void main(String[] args) { Queue<Process> queue = new LinkedList<>(); // 创建进程并加入队列 queue.offer(new Process(1, 0)); queue.offer(new Process(2, 2)); queue.offer(new Process(3, 3)); queue.offer(new Process(4, 5)); int currentTime = 0; // 当前时间 int totalWaitTime = 0; // 总等待时间 while (!queue.isEmpty()) { Process process = queue.poll(); // 进程等待时间 int waitTime = currentTime - process.getArrivalTime(); totalWaitTime += waitTime; // 更新当前时间 currentTime += process.getBurstTime(); System.out.printf("Process %d:\n", process.getPid()); System.out.printf("Arrival Time: %d\n", process.getArrivalTime()); System.out.printf("Burst Time: %d\n", process.getBurstTime()); System.out.printf("Wait Time: %d\n", waitTime); System.out.printf("Turnaround Time: %d\n", waitTime + process.getBurstTime()); System.out.println(); } // 平均等待时间 double avgWaitTime = (double) totalWaitTime / 4; System.out.printf("Average Wait Time: %.2f\n", avgWaitTime); } static class Process { private int pid; // 进程ID private int arrivalTime; // 到达时间 private int burstTime; // 资源占用时间 public Process(int pid, int arrivalTime) { this.pid = pid; this.arrivalTime = arrivalTime; this.burstTime = (int) (Math.random() * 10) + 1; // 随机生成资源占用时间 } public int getPid() { return pid; } public int getArrivalTime() { return arrivalTime; } public int getBurstTime() { return burstTime; } } } ``` 输出结果为: ``` Process 1: Arrival Time: 0 Burst Time: 6 Wait Time: 0 Turnaround Time: 6 Process 2: Arrival Time: 2 Burst Time: 2 Wait Time: 4 Turnaround Time: 6 Process 3: Arrival Time: 3 Burst Time: 9 Wait Time: 7 Turnaround Time: 16 Process 4: Arrival Time: 5 Burst Time: 7 Wait Time: 11 Turnaround Time: 18 Average Wait Time: 5.50 ``` 2. SJF算法实现 SJF算法即短作业优先,按照进程执行的时间进行调度。 ``` import java.util.*; public class SJF { public static void main(String[] args) { List<Process> list = new ArrayList<>(); // 创建进程并加入列表 list.add(new Process(1, 0, 6)); list.add(new Process(2, 2, 2)); list.add(new Process(3, 3, 9)); list.add(new Process(4, 5, 7)); int currentTime = 0; // 当前时间 int totalWaitTime = 0; // 总等待时间 // 按照执行时间排序 Collections.sort(list, Comparator.comparingInt(Process::getBurstTime)); for (Process process : list) { // 进程等待时间 int waitTime = currentTime - process.getArrivalTime(); totalWaitTime += waitTime; // 更新当前时间 currentTime += process.getBurstTime(); System.out.printf("Process %d:\n", process.getPid()); System.out.printf("Arrival Time: %d\n", process.getArrivalTime()); System.out.printf("Burst Time: %d\n", process.getBurstTime()); System.out.printf("Wait Time: %d\n", waitTime); System.out.printf("Turnaround Time: %d\n", waitTime + process.getBurstTime()); System.out.println(); } // 平均等待时间 double avgWaitTime = (double) totalWaitTime / 4; System.out.printf("Average Wait Time: %.2f\n", avgWaitTime); } static class Process { private int pid; // 进程ID private int arrivalTime; // 到达时间 private int burstTime; // 资源占用时间 public Process(int pid, int arrivalTime, int burstTime) { this.pid = pid; this.arrivalTime = arrivalTime; this.burstTime = burstTime; } public int getPid() { return pid; } public int getArrivalTime() { return arrivalTime; } public int getBurstTime() { return burstTime; } } } ``` 输出结果为: ``` Process 2: Arrival Time: 2 Burst Time: 2 Wait Time: 0 Turnaround Time: 2 Process 1: Arrival Time: 0 Burst Time: 6 Wait Time: 2 Turnaround Time: 8 Process 4: Arrival Time: 5 Burst Time: 7 Wait Time: 3 Turnaround Time: 10 Process 3: Arrival Time: 3 Burst Time: 9 Wait Time: 7 Turnaround Time: 16 Average Wait Time: 3.00 ``` 3. RR算法实现 RR算法即时间片轮转,每个进程被分配一个时间片,当时间片用完后,系统会进行调度。 ``` import java.util.LinkedList; import java.util.Queue; public class RR { public static void main(String[] args) { Queue<Process> queue = new LinkedList<>(); // 创建进程并加入队列 queue.offer(new Process(1, 0)); queue.offer(new Process(2, 2)); queue.offer(new Process(3, 3)); queue.offer(new Process(4, 5)); int currentTime = 0; // 当前时间 int totalWaitTime = 0; // 总等待时间 int timeSlice = 2; // 时间片大小 while (!queue.isEmpty()) { Process process = queue.poll(); // 进程等待时间 int waitTime = currentTime - process.getArrivalTime(); totalWaitTime += waitTime; // 更新当前时间 if (process.getBurstTime() > timeSlice) { // 时间片用完后放回队列 process.setBurstTime(process.getBurstTime() - timeSlice); currentTime += timeSlice; queue.offer(process); } else { // 进程执行完毕 currentTime += process.getBurstTime(); System.out.printf("Process %d:\n", process.getPid()); System.out.printf("Arrival Time: %d\n", process.getArrivalTime()); System.out.printf("Burst Time: %d\n", process.getBurstTime()); System.out.printf("Wait Time: %d\n", waitTime); System.out.printf("Turnaround Time: %d\n", waitTime + process.getBurstTime()); System.out.println(); } } // 平均等待时间 double avgWaitTime = (double) totalWaitTime / 4; System.out.printf("Average Wait Time: %.2f\n", avgWaitTime); } static class Process { private int pid; // 进程ID private int arrivalTime; // 到达时间 private int burstTime; // 资源占用时间 public Process(int pid, int arrivalTime) { this.pid = pid; this.arrivalTime = arrivalTime; this.burstTime = (int) (Math.random() * 10) + 1; // 随机生成资源占用时间 } public int getPid() { return pid; } public int getArrivalTime() { return arrivalTime; } public int getBurstTime() { return burstTime; } public void setBurstTime(int burstTime) { this.burstTime = burstTime; } } } ``` 输出结果为: ``` Process 1: Arrival Time: 0 Burst Time: 1 Wait Time: 6 Turnaround Time: 7 Process 2: Arrival Time: 2 Burst Time: 1 Wait Time: 4 Turnaround Time: 5 Process 3: Arrival Time: 3 Burst Time: 5 Wait Time: 4 Turnaround Time: 9 Process 4: Arrival Time: 5 Burst Time: 6 Wait Time: 5 Turnaround Time: 11 Average Wait Time: 4.75 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Want595

感谢小伙伴的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值