进程调度算法
先来先服务调度算法(FCFS)
- 每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或者被阻塞,才会继续从队列中选择第一个进程接着运行;
- 适用于CPU繁忙性作业的系统,而不适用于I/O繁忙性作业的系统;
最短作业优先调度算法(SJF)
- 会优先选择运行时间最短的进程来运行,有助于提高系统的吞吐量;
- 会出现一种极端现象,长作业在就绪队列中等待,不断的往后推,周转时间边长,导致长作业长时间不会被运行;
高响应比优先调度算法(HRRN)
- 每次进行进程调度时,先计算【响应比优先级】,然后把【响应比优先级】最高的进程投入运行;
- 响应比优先级 = (等待时间 + 要求服务时间)/ 要求服务时间;
过程:
- 如果两个进程的【等待时间】相同,【要求的服务时间】越短,【响应比】就越高,这样短作业的进程容易被选中运行;
- 如果两个进程的【要求服务时间】相同,【等待时间】越长,【响应比】就越高,这样就可以兼顾到长作业;
时间片轮询调度算法(RR)
每个进程分配一个时间段,称为时间片,即允许该进程在该时间段中运行;
- 如果时间片用完,进程仍在运行,那么将会把此进程从CPU释放出来,并把CPU分配另外一个进程;
- 如果该进程在时间片结束前阻塞或者结束,则CPU立即进行切换;
- 如果时间片设得太短会导致过多的进程上下文切换,降低了CPU的效率;
- 如果时间片设得太长会导致对短作业进程响应的时间边长。
最高优先级调度算法(HPF)
从就绪队列中选择最高优先级的进程进行运行;
- 静态优先级:创建进程时候,就已经确定了优先级,然后整个运行时间优先级都不会变化;
- 动态优先级:如果进程运行时间增加,则降低其优先级;如果进程的等待时间增加,就增加其优先级,也就是随着时间的推移增加等待进程的优先级;
- 非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程;
- 抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行。
多级反馈队列调度算法
概念:
多级:表示有多个队列,每个队列优先级从高到低,同时优先级越高时间片越短;
反馈:表示如果有新的进程加入优先级高的队列中,立刻停止当前正在运行的进程,转而去运行优先级高的队列;
- 设置了多个队列,赋予每个队列不同的优先级,每个队列优先级从高到低,同时优先级越高时间片越短;
- 新的进程会被放入到第一级队列的末尾,按照先来先服务的原则排队等待被调度,如果在第一级队列规定的时间片没运行完成,则将其转入到第二级队列的末尾,以此类推直到完成;
- 当较高优先级的队列为空,才调度较低优先级的队列中的进程运行。如果进程运行时,有新进程进入较高优先级的队列,则停止当前运行的进程并将其移入到原队列末尾,接着让较高优先级的进程运行。
页面置换算法
当出现缺页异常,需要调入新页面而内存已满时,选择被置换的物理页面;也就是说选择一个物理页面换出到磁盘,然后把需要访问的页面换入到物理页;
OPT(最佳页面置换算法)
- 置换在未来最长不访问的页面;
- 作用是为了衡量你的算法的效率,你的算法效率越接近该算法的效率,那么说明你的算法是高效的。
FIFO(先进先出置换算法)
选择在内存驻留时间很长的页面进行置换。
LRU(最近最久未使用的置换算法)
可以引申到linkedHashMap,参考:https://blog.nowcoder.net/n/faeb92831c4d4d02a62edb5d0fb2cf8a
- 在发生缺页时,选择最长时间没有被访问的页面进行置换;
- 开销大,因为在每次访问内存的时候都要维护、更新一个所有页面的链表,是非常耗时的操作。
Lock(时钟页面置换算法)
把所有页面保存在一个类似钟面的【环形链表】中,一个表针指向最老的页面;
过程:
- 如果它的访问位是0就淘汰该页面,并把新的页面插入到这个位置,然后把表针前移一个位置;
- 如果访问位是1就清除访问位(修改为0),并把表针前移一个位置,重复这个过程直到找到一个访问位为0的页面为止。
LFU(最不常用置换算法)
在发生缺页时,选择访问次数最少的页面将其淘汰;
实现方式
对每一个页面设置一个【访问计数器】,每当一个页面被访问时,该页面的访问计数器就累积1。在发生缺页的时候,淘汰计数器值最小的那个页面;
缺点
- 增加一个计数器,对硬件的成本比较高;
- 如果要对这个计数器查找那个页面访问次数最小,查找链表本身,如果链表长度很大,是非常耗时的,效率不高。
磁盘调度算法
- 先来先服务算法
- 最短寻道时间优先算法
- 扫描算法
- 循环扫描算法
- LOOk与C-LOOK算法