- A+
所属分类:Linux系统
上次我们讲到了主调度器。然后提及了下组调度。
今天我们来看下组调度。
static struct task_struct *pick_next_task_fair(struct rq *rq) { struct task_struct *p; struct cfs_rq *cfs_rq = &rq->cfs; struct sched_entity *se; if (!cfs_rq->nr_running) return NULL; do { se = pick_next_entity(cfs_rq); set_next_entity(cfs_rq, se); cfs_rq = group_cfs_rq(se); } while (cfs_rq); p = task_of(se); if (hrtick_enabled(rq)) hrtick_start_fair(rq, p); return p; }
代码很简单,其实在2.4以前是没有组调度的。就不会有group_cfs_rq这个队列,那么所有task都在全局的rq->cfs,就是刚开始的。
后面为了引入分组的概念,就有了组调度。
引入分组的概念后,原来对task直接进行的操作就变得不那么遍历,就引入了sched_entity。整体结构如下。
结合代码理解下
- 首先代码 struct cfs_rq *cfs_rq = &rq->cfs; 拿到全局的cfs_rq。
- 然后进行一次pick 拿到sched_entity se(假设是A cfs_rq) -----------sched_entity 和 task_group是可以相互转换的
- 然后把全局的cfs_rq 复制成现在的cfs_rq(假设是A cfs_rq)
- 然后是while循环,如果A下面没有节点了,就结束循环,但是A下面还有节点,就循环,再重新赋值,如此如此。知道根部。
- 那么假设我们在A的下面 task_gruop1 停止了,因为它的cfs_rq是空的。
- 接下来就把task_group1 转换成task_struck p。
- 最后就结束返回。
同理rt队列也是这样的:如果主调度器(),选择的是rt_sched_class 那就 pick_next_task_rt
那么就会从task_group A 的rt_rq开始调度
task_group不仅仅有cfs_rq 还有 rt_rq。
关于task_group 和组调度的详细我们接下来会详细分析。
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏