Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1125607
  • 博文数量: 145
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1925
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(145)

文章存档

2020年(43)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: LINUX

2020-08-10 15:53:57

之前一篇文章讲了linux当中的调度,今天来一篇讲讲linux当中最普遍的完全公平调度。
如前文所述,某种调度,最核心的就是其调度类了,完全公平调度类的结构如下:

点击(此处)折叠或打开

  1. const struct sched_class fair_sched_class = {
  2.     .next            = &idle_sched_class,// 它下来就是idle了
  3.     .enqueue_task        = enqueue_task_fair,// 队列操作,每一个调度类,操作涉rq当中的一个子队列
  4.     .dequeue_task        = dequeue_task_fair,
  5.     .yield_task        = yield_task_fair,
  6.     .yield_to_task        = yield_to_task_fair,

  7.     .check_preempt_curr    = check_preempt_wakeup,

  8.     .pick_next_task        = __pick_next_task_fair,
  9.     .put_prev_task        = put_prev_task_fair,
  10.     .set_next_task = set_next_task_fair,
  11. ...
  12.     .task_tick        = task_tick_fair,
  13.     .task_fork        = task_fork_fair,

  14.     .prio_changed        = prio_changed_fair,
  15.     .switched_from        = switched_from_fair,
  16.     .switched_to        = switched_to_fair,

  17.     .get_rr_interval    = get_rr_interval_fair,

  18.     .update_curr        = update_curr_fair,
  19. ..
  20. };
cfs对应的调度子队列的结构为:

点击(此处)折叠或打开

  1. struct cfs_rq {
  2.     struct load_weight    load;
  3.     unsigned long        runnable_weight;
  4.     unsigned int        nr_running;
  5.     unsigned int        h_nr_running; /* SCHED_{NORMAL,BATCH,IDLE} */
  6.     unsigned int        idle_h_nr_running; /* SCHED_IDLE */

  7.     u64            exec_clock;
  8.     u64            min_vruntime;// 内核会不断递增
  9.     /*仅包含两个结构rb_root和 rb_leftmost*/
  10.     struct rb_root_cached    tasks_timeline;
  11.     /**/

  12.     /*
  13.      * 'curr' points to currently running entity on this cfs_rq.
  14.      * It is set to NULL otherwise (i.e when none are currently running).
  15.      */
  16.     struct sched_entity    *curr;
  17.     struct sched_entity    *next;
  18.     struct sched_entity    *last;
  19.     struct sched_entity    *skip;
  20. ...
  21. };
整个队列的管理关键在于变量rb_root_cached,它的结构如下:

点击(此处)折叠或打开

  1. struct rb_root_cached {
  2.     struct rb_root rb_root;//红黑树根节点
  3.     struct rb_node *rb_leftmost;// 红黑树当中最左节点
  4. };
这两个成员就把整个cfs队列当中的所有可以调度的进程管理好了,每次取最小,直接拿出rb_leftmost即可
完全公平调度依赖于虚拟时钟,用这个度量进程在这个体系当中得到的CPU时间。它在计算一个进程的运行时间的时候,会把实际运行的时间除以各个进程的优先级,这样,优先级高的进程明明花费了相同的时间,但是除以优先级之后,反而虚拟时间较少,这样,排序就靠前,下次就极有可能被调度了。



阅读(854) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~