1.调度器的概述
多任务操作系统分为非抢占式多任务和抢占式多任务。与大多数现代操作系统一样,Linux采用的是抢占式多任务模式。这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器。调度器决定了什么时候停止一个进程以便让其他进程有机会运行,同时挑选出一个其他的进程开始运行。
2.调度策略
在Linux上调度策略决定了调度器是如何选择一个新进程的时间。调度策略与进程的类型有关,内核现有的调度策略如下:
#define SCHED_NORMAL 0
#define SCHED_FIFO 1
#define SCHED_RR 2
#define SCHED_BATCH 3
/* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE 5
0: 默认的调度策略,针对的是普通进程。
1:针对实时进程的先进先出调度。适合对时间性要求比较高但每次运行时间比较短的进程。
2:针对的是实时进程的时间片轮转调度。适合每次运行时间比较长得进程。
3:针对批处理进程的调度,适合那些非交互性且对cpu使用密集的进程。
SCHED_ISO:是内核的一个预留字段,目前还没有使用
5:适用于优先级较低的后台进程。
注:每个进程的调度策略保存在进程描述符task_struct中的policy字段
3.调度器中的机制
内核引入调度类(struct sched_class)说明了调度器应该具有哪些功能。内核中每种调度策略都有该调度类的一个实例。(比如:基于公平调度类为:fair_sched_class,基于实时进程的调度类实例为:rt_sched_class),该实例也是针对每种调度策略的具体实现。调度类封装了不同调度策略的具体实现,屏蔽了各种调度策略的细节实现。
调度器核心函数schedule()只需要调用调度类中的接口,完成进程的调度,完全不需要考虑调度策略的具体实现。调度类连接了调度函数和具体的调度策略。
- 调度类就是代表的各种调度策略,调度实体就是调度单位,这个实体通常是一个进程,但是自从引入了cgroup后,这个调度实体可能就不是一个进程了,而是一个组
-
【文章福利】小编推荐自己的Linux内核技术交流群: 【977878001】整理一些个人觉得比较好得学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前100进群领取,额外赠送一份 价值699的内核资料包(含视频教程、电子书、实战项目及代码)
内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料
4.schedule()函数
linux 支持两种类型的进程调度,实时进程和普通进程。实时进程采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL策略。
preempt_disable():禁止内核抢占
cpu_rq():获取当前cpu对应的就绪队列。
prev = rq->curr;获取当前进程的描述符prev
switch_count = &prev->nivcsw;获取当前进程的切换次数。
update_rq_clock() :更新就绪队列上的时钟
clear_tsk_need_resched():清楚当前进程prev的重新调度标志。
deactive_task():将当前进程从就绪队列中删除。