目录
2.7 实时调度类
2.7.1 性质
2.7.2 数据结构
2.7.3 调度器操作
2.7 实时调度类
完全公平调度器类,即CFS。
作用:调度普通进程。
实时调度器类,即RT。
作用:调度实时进程。
2.7.1 性质
RT调度类包含两种策略policy:
SCHED_RR:
即循环调度。每个进程分配固定时间片,优先级高的进程先执行,时间片用完的进程移到就绪队列尾部,所有进程时间片用完后,重新配置时间片,相同优先级依次执行。
SCHED_FIFO:
不依赖时间片,进程被调度后除非主动放弃CPU,否则一直运行,按队列顺序依次执行。
CFS调度器:
通过红黑树来组织进程的调度实体se,选择树的最左节点为下一个待执行进程。
RT调度器:
通过优先级队列(优先级数组链表)组织实时调度实体。
2.7.2 数据结构
struct sched_class rt_sched_class = {
.next = &fair_sched_class, //下一个调度类
.enqueue_task = enqueue_task_rt,
.dequeue_task = dequeue_task_rt,
.yield_task = yield_task_rt,
.check_preempt_curr = check_preempt_curr_rt,
.pick_next_task = pick_next_task_rt,
.put_prev_task = put_prev_task_rt,
.select_task_rq = select_task_rq_rt,
.set_cpus_allowed = set_cpus_allowed_rt,
.set_curr_task = set_curr_task_rt,
.task_tick = task_tick_rt,
.update_curr = update_curr_rt,
};
RT比CFS简单
struct rq { //每个CPU一个struct rq
struct cfs_rq cfs;
struct rt_rq rt; 表示RT调度类的就绪队列
}
struct rt_rq {
struct rt_prio_array active;
unsigned int rt_nr_running; RT队列中进程数量
}
struct rt_prio_array {
unsigned long bitmap[BITS_TO_LONGS(MAX_RT_PRIO+1)];
//MAX_RT_PRIO=99
struct list_head queue[MAX_RT_PRIO];
};
bitmap:
每个优先级一个bit,一个long数组成员可表示32位,99个优先级需要4个数组成员。
位图:表示对应优先级链表是否有进程。
相同优先级的实时进程在同一链表中,表头是:
struct rt_prio_array active.queue[prio]
update_curr_rt:
更新rt_se的sum_exec_runtime。
计算时间是实际时间,不是CFS那种虚拟时间。
2.7.3 调度器操作
const struct sched_class rt_sched_class = {
.enqueue_task = enqueue_task_rt, 将进程加入rt队列。
.dequeue_task = dequeue_task_rt, 将进程移出rt队列。
}
enqueue_task_rt和dequeue_task_rt:
都会操作active.queue[p->prio]对应链表,实现加入、删除进程。
加入:设置bitmap中对应优先级的bit。
删除:清除bitmap对应优先级的bit。
RT两个调度策略policy:
SCHED_FIFO:
必须显式自动放弃CPU(yield_task_rt),否则一直执行。
SCHED_RR:
时间片用尽后,重新设置时间片并排队到RT就绪队列末尾,并设置TIF_NEED_RESCHED。
系统调用sched_setscheduler:
作用:修改进程的优先级,调度类,调度策略:
即更改task_struct->prio,task_struct->sched_class,task_struct->policy