本文主要是介绍schedule与CFS算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、调度类与调度实体
调度类是系统为了对不同进程调度进行区分而用的数据结构,其中记录了关于调度不同进程所需要的函数,每种调度算法都有其自己的调度类
调度实体是每个进程都有的数据结构,其中记录了调度此进程所需要使用的所有信息,且普通进程和实时进程有着不同的调度实体
关于不同种类的进程,主要是3种,普通进程、实时进程以及空闲进程(idle)
#define SCHED_NORMAL 0 /* 普通进程调度策略,即CFS算法 */
#define SCHED_FIFO 1 /* 实时进程的调度策略 */
#define SCHED_RR 2 /* 实时进程的调度策略 */
#define SCHED_BATCH 3
#define SCHED_IDLE 5 /* 空闲进程 */
#define SCHED_RESET_ON_FORK 0x40000000
SCHED_FIFO代表先入先出的调度算法:不使用时间片,一旦一个此种调度策略的进程处于可执行状态就会一直执行,直到它自己受阻塞或者释放处理器,只有更高级的SCHED_FIFO和SCHED_RR任务能够抢占它。
SCHED_RR代表实时轮流调度算法,与前者大体相同,只是其中每个任务都有着时间片,当耗完了时间片就不能再继续执行,时间片耗尽后同优先级的其他实时进程会被轮流调度。
SCHED_NORMAL代表普通进程的调度策略,我看的是2.6.32版本的内核代码,使用的是CFS(完全公平调度算法)。当系统中有实时进程时,普通进程是不会被调度执行的,只有当实时进程都结束以后才开始运用此调度算法选择普通进程运行
二、schedule函数主要流程
schedule()是进程调度的主要入口,作用是选择下一个运行的进程,且它在每次的进程选择时会找到最高优先级的调度类,每个调度类都有其自己的就绪队列,然后再从其中找出下一个该运行的进程。
首先声明了调度中需要用到的一些数据结构
asmlinkage void __sched schedule(void)
{struct task_struct *prev, *next; unsigned long *switch_count; struct rq *rq;int cpu;
禁止内核抢占,获取当前cpu的编号,获取当前cpu对应的就绪队列rq,当前进程的描述符prev,获取当前进程的切换次数switch_count,释放大内核锁,完成对时间调试的检查与统计
preempt_disable(); cpu = smp_processor_id(); rq = cpu_rq(cpu); rcu_sched_qs(cpu); prev = rq->curr; switch_count = &prev->nivcsw;
这篇关于schedule与CFS算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!