“启动太阳轨道计算软件‘Three-Body l.0’!”牛顿声嘶力竭地发令,“启动计算主控!加载差分模块!加载有限元模块!加载谱方法模块……调入初始条件参数!计算启动!!”
本文将对linux中进程调度相关知识进行介绍。
准备知识
进程分类
根据进程运行状态,可以将进程分为两种:
- IO密集型:吞吐量大,CPU占用率低,例如网络通信中的监听进程
- CPU密集型:吞吐量少,CPU占用率高,例如编译器进程
由于进程的不同表现,我们实际上会采取不同的策略,IO密集型往往是交互进程,响应时间敏感,属于高优先级;而CPU密集型,例如编译器进程,响应要求不高,因此属于低优先级。对于时间响应敏感的,我们要奖励,占用CPU资源多的,我们要惩罚。
graph LR start((start)) ioTask[IO密集型] cpuTask[CPU密集型] bonus[奖励, 提高优先级] panish[惩罚, 降低优先级] start --> ioTask start --> cpuTask ioTask --> bonus cpuTask --> panish
进程优先级
根据进程重要性,可以将进程分为:
- 实时进程
- 普通进程
实时进程相对重要,需要保证CPU占用优先级,普通进程不需额外照顾,linux中影响优先级的两个因素:Nice值(谦让值)和priority(权重),优先级和权重的关系如下:
实时进程PR值范围是0~99,数值越大被调度优先级越高
普通进程PR值范围是100~139,数值越小被调度优先级越高
Nice值范围是-20~19,并不是优先级但影响PR值,一般作用在普通进程上
PR值由内核决定,而用户态可以修改Nice值,干预PR值
Nice值为谦让值,如果为0,表示不干预内核,听天由命;如果为负值,表示用户态干预提高优先级,将机会留给自己;如果为正,表示降低优先级,将机会留给别人。下面这张图很形象:
抢占与非抢占
说完了任务类型,我们再来聊聊调度类型,根据进程在占用CPU时,使用权是否被剥夺,我们可以将调度分为如下两种:
- 非抢占式:进程任务一旦占据CPU,只有当前任务完成或等待IO时释放CPU,不能被其他进程夺走
- 抢占式:任务占用CPU期间可以被抢占,由操作系统调度器决定下一个占用CPU的任务
Linux采用抢占式,CPU利用率和响应时间较好,但是增加了开销
调度器设计指标
设计调度器的时候,需要考虑两个指标:
- 周转时间:任务从开始排队等待CPU资源到任务完成的时间差,即等待+执行的时间
- 响应时间:任务从开始排队到开始使用CPU的时间差,即等待时间
综合来说,有如下几点设计经验:
实时进程优先调度,普通进程优先级低于实时进程
IO密集型要频繁调度,分配较短时间片,少食多餐
CPU密集型要稍微惩罚,分配长时间片,多食少餐
调度算法
以下介绍几种常见的调度算法,记住:没有银弹
FIFO调度
经典的先来先服务