调度
调度算法背景
上下文切换:
- 切换CPU的当前任务,从一个进程/线程到另一个
- 保存当前进程/线程在PCB/TCB中执行上下文(CPU状态)
- 读取下一个进程/线程上下文
CPU调度:
- 从就绪队列中挑选一个进程/线程作为CPU将要运行的下一个进程/线程
- 调度程序:挑选进程/线程的内核函数(通过一定的调度策略)
- 什么时候进行调度:从一个状态切换到另一个状态时就会触发一次调度,尤其是与运行状态相关的切换
内核运行调度程序的条件:
- 一个进程从运行状态切换到等待状态
- 一个进程被终结
不可抢占调度:
- 调度必须等待事件/进程结束,不允许其他进程打断某一进城运行,效率有可能不高,主要是早期OS。
可以抢占调度:
- 调度程序在终端被响应后执行
- 当前的进程从运行切换到就绪,或者一个进程从等待切换到就绪
- 当前运行的进程可以被换出
用户进程感觉不对被调度,由操作系统决定调度那个进程,现代操作系统常用。策略是针对用户态进程,进程在内核中通过系统调用执行,因为系统调用返回时是到发起这个调用的进程继续执行,所以内核中不会切换,抢占。只要进程在系统调用时不存在从运行态到阻塞态的变化,OS可以确保返回正常。
如果在内核中也允许这种抢占,系统调用返回时不是原来的进程而是另一个优先级更高的进程,就是内核中的抢占。
早期是完全不可抢占,后来用户态进程允许抢占,现在内核态进程也可以抢占。
调度原则
进程等待io时可以将CPU交给其他进程
评价指标:
- CPU使用率:CPU处于忙状态所占时间的百分百
- 吞吐量:在单位时间完成的进程数量,比如数据库完成的事物等。操作系统的计算带宽
- 周转时间:一个进程从初始化到结束,包括所有等待时间锁花费的时间
- 等待时间:进程在就绪队列中的总时间,而不是阻塞时间
- 响应时间:从一个进程被提交到到第一次响应的总时间,越快越好。操作系统计算的延迟
调度算法期望:
各个指标是矛盾的不能完全兼顾
- 减少响应时间:及时处理用户的输入并尽快将输出提供给用户
- 减少平均响应时间的波动:在交互系统中,可预测性比高差异低平均更重要
- 增加吞吐量:【1】减少系统以及上下文切换的开销【2】高线利用CPU、io等系统资源
- 减少等待时间:减少每个进程的等待时间
调度公平:
- 期望操作系统中每个进程都等待相同的时间
调度算法
FCFS(先来先服务)
- 按照进程到来先后顺序,进程先来先服务。如果前一进程运行时间过长会影响后续进程,且平均周转时间也会越长
- 如果进程执行过程中阻塞,队列中下一个进程会得到CPU
优点:
- 简单
缺点:
- 平均等待时间波动较大
- 花费时间少的任务可能排在花费时间长的任务后面
- 可能导致io与CPU之间的重叠处理,CPU密集型进程会导致io闲置,io密集型进程会导致进程等待
- 没有考虑抢占
SPN(SJF) SRT (短进程优先(短作业优先) 短剩余时间优先)
选择下一个最短的进程
- 非抢占式:当一个新的进程到来时比当前任务时间还短,将其排在队列最前端不打断当前任务
- 可抢占:比较剩余时间可打断当前任务 (SRT)
缺点:
可能导致饥饿:
- 连续的短任务回事长任务饥饿
- 短任务可用时的任何长任务的CPU时间都会增加平均等待时间
需要预知未来:
- 怎么预支下一个CPU突发的持续时间
- 简单解决办法:询问用户
- 如果用户欺骗就杀死进程
- 如果用户不知道怎么办
根据执行历史估计将来CPU突发的持续时间
HRRN(最高响应比优先)
- 在SPN基础上改进算法,饥饿现象得到了有效地缓解
- 不可抢占
- 关注了进程等待了多长时间
- 防止无限期推迟
公式:
$ R = \dfrac{w+s}{s} $
w:等待时间
s:执行时间
R:响应比
选择R值最高的程序
Robin Robin(轮询)
设定时间片,各个进程轮流执行,不足时间片的直接切换到下一任务
额外花销:
上下文切换
关键:选择一个合适的时间量子:
- 时间量子太大:等待时间过长;极端情况将退化成FCFS
- 时间量子太小:反应迅速,但吞吐量由于大量上下文切换而受到影响
早期性能不足LINUX一般为1%秒,性能提高后一般为0.1%秒
目标:
- 选择一个合适的时间量子,根据经验控制在上下文开销处于1%以内
Multilevel Feedback Queues(多级反馈队列)
将就绪队列划分成不同队列:
但进程可能在运行开始是交互较多,后期计算较多,从一开始就分配好队列很难满足进程的需求,多级反馈队列可以在不同队列中移动,比如CPU比较多的进程优先级越来越低,反之越来越高,使io密集任务等需要响应的进程很快进行,cpu优先级低
- 时间量子随着优先级增加而增加
- 如果任务在当前的时间量子中没有完成,则降至下一优先级
优点:
- CPU密集型任务的优先级下降的很快
- io密集型任务停留在高优先级
Fair Share Scheduling(公平共享调度)
用户级别的公平调用,例子:某高性能计算机供多人进行科学计算,用户A开1个进程,用户B开20个进程
一些用户组比其他组更重要,保证不重要的组无法垄断资源,未使用的资源按照每个组所分配的资源的比例来分配,没有达到资源使用率目标的组获得更高的优先级
各个调度算法总结对比:
调度算法评价调度方法:
- 确定性建模,对确定的工作量计算每个算法的表现
- 队列模型:用来处理随机工作负载的数学方法
- 实现/模拟:建立一个允许算法运行实际数据的系统,最灵活,一般性
最好还是在真实机器上跑一遍看效率,因为和硬件也有关系
实时调度(real-time)
常用于嵌入式控制环境,调度火车,工厂,需要确保任务在规定时间内完成的
实时调度定义:正确性依赖于其时间和功能两方面的一种OS
性能指标:时间约束的及时性(deadlines),速度和平均性能相对不重要,重点是时间约束的可预测性。
特征
- 及时性
- 可预测性
类别
- 硬实时系统/强实时系统:如果某个任务没完成有灾难性后果,在设定的时间内必须完成。如控制水坝。
- 软实时系统/弱实时系统:重要的进程优先级更高,要尽量完成,如看视频,帧数没控制好会掉帧。
任务/工作单元job:一次计算,一次文件读取,一次信息传递等等
属性:取得进展所需要的资源和实时参数
release time 进程处于就绪态的时间
relative deadline: 任务是间隔时间段完成,每个任务有个特定的时间,要在特定的时间段内完成
absolute deadline:最终的结束时间
周期任务,有规律的重复
周期P=inter-realease time=relative deadline (0 < p)
执行时间e,最大执行时间< p
使用率/利用率U=e/p
hard real-time—hard deadline:保证确定性
soft real-time—-soft deadline
实时系统两类:
- RM rate monotonic 速率单调调度
静态最佳,根据周期安排优先级,越短优先级越高 ,执行周期最短的任务,优先级一开始确定 - EDF earliest deadline first 最早期限调度 (动态调度算法)
最佳动态优先级调度,deadline越早优先级越高,执行deadline最早的任务
多处理器调度
需要考虑:
- 任务在哪个CPU上执行
- 公平性
- 负载平衡
优先级反转
低优先级影响高优先级的现象
首先只有T3执行,在t2时刻访问了共享资源,在t3时刻T1进程到来,由于T1优先级高切换至T1,在t4时刻T1需要访问共享资源,由于T1未使用完毕,T1等待T3,此时T2打断T3,最高优先级的T1需要等待T2T3执行完毕才能执行,产生优先级反转现象。
解决办法1:优先级继承,在T1访问共享资源时动态将T3优先级提到T1的优先级
解决办法2:优先级天花板,资源的优先级=所有可以锁定该资源的任务中优先级最高的那个任务的优先级。事先统计。一旦某任务占用该资源,则优先级提升为资源的优先级。不论阻塞是否发生。
除非优先级高于系统中所有被锁定的资源的优先级上限,否则任务在尝试执行临界区的时候会被阻塞。
持有最高优先级上限信号量锁的任务,会继承被该锁阻塞的任务的优先级