基于Linux 4.5的进程模型与调度器分析(7)

/*
    * leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
    * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
    * (like users, containers etc.)
    *
    * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
    * list is used during load balance.
    */
    int on_list;
    struct list_head leaf_cfs_rq_list;
    struct task_group *tg;    /* group that "owns" this runqueue */

#ifdef CONFIG_CFS_BANDWIDTH
    int runtime_enabled;
    u64 runtime_expires;
    s64 runtime_remaining;

u64 throttled_clock, throttled_clock_task;
    u64 throttled_clock_task_time;
    int throttled, throttle_count;
    struct list_head throttled_list;
#endif /* CONFIG_CFS_BANDWIDTH */
#endif /* CONFIG_FAIR_GROUP_SCHED */
};

一些成员变量的含义:

成员   描述  
nr_running   队列上可运行进程的数目  
h_nr_running   只对进程组有效,其下所有进程组中cfs_rq的nr_running总和  
load   就绪队列上可运行进程的累计负荷权重(总负载)  
min_vruntime   跟踪记录队列上所有进程的最小虚拟运行时间. 这个值是实现与就绪队列相关的虚拟时钟的基础。当更新当前运行任务的累计运行时间时或者当任务从队列删除去,如任务睡眠或退出,这时候会查看剩下的任务的vruntime是否大于min_vruntime,如果是则更新该值。  
tasks_timeline   用于在按时间排序的红黑树中管理所有进程(红黑树的root)  
rb_leftmost   总是设置为指向红黑树最左边的节点, 即需要被调度的进程. 该值其实可以可以通过病例红黑树获得, 但是将这个值存储下来可以减少搜索红黑树花费的平均时间  
curr   当前正在运行的sched_entity(对于组虽然它不会在cpu上运行,但是当它的下层有一个task在cpu上运行,那么它所在的cfs_rq就把它当做是该cfs_rq上当前正在运行的sched_entity  
next   表示有些进程急需运行,即使不遵从CFS调度也必须运行它,调度时会检查是否next需要调度,有就调度next  
skip   略过进程(不会选择skip指定的进程调度)  
    CFS调度的原理:

    在理想状态下时每个进程都能获得相同的时间片,并且同时运行在CPU上,但实际上一个CPU同一时刻运行的进程只能有一个。 也就是说,当一个进程占用CPU时,其他进程就必须等待。而往往有一些需要优先去占用CPU的进程,所以实际上我们是根据每个进程的权重来分配每个进程的运行时间,越重要的进程,我们设置的权重就越高。

    而前面说过,调度还有一个重要的意义在于要对所有进程尽可能地公平分配时间,可是从分配时间来看,权重越高的似乎分配到的运行时间就会越多,并没有让人感觉到公平,于是CFS引入了一个变量 : 虚拟运行时间(virtual runtime) ,它会惩罚当前正在运行的进程,以使那些正在等待的进程下次被调度。用vruntime的大小来衡量哪个进程是最优先需要被调度的。

    虚拟运行时间计算公式为:一次调度间隔的vruntime = 实际运行时间 * NICE_0_LOAD / 进程权重;

    其中代码NICE_0_LOAD对应的是nice为0的进程的权重值为1024,而所有进程都以nice为0的进程的权重1024作为基准,计算自己的vruntime增加速度。(见后面公式)

/*nice和权重值的转换表*/
static const int prio_to_weight[40] = { 
 /* -20 */    88761,    71755,    56483,    46273,    36291, 
 /* -15 */    29154,    23254,    18705,    14949,    11916, 
 /* -10 */    9548,    7620,      6100,      4904,      3906, 
 /*  -5 */    3121,    2501,      1991,      1586,      1277, 
 /*  0 */    1024,      820,      655,      526,      423, 
 /*  5 */      335,      272,      215,      172,      137, 
 /*  10 */      110,      87,        70,        56,        45, 
 /*  15 */      36,      29,        23,        18,        15, 
};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/12804.html