我已经阅读了一些我可以知道的事情,而不是使用调度策略调度任务,我们最好安排一个具有调度策略的实体。优点是您可以使用相同的计划策略安排许多事情。因此,为两个调度策略(CFS和RT)定义了两个实体,即sched_entity
和sched_rt_entity
。 CFS实体的代码是(来自v3.5.4)
struct sched_entity {
struct load_weight load; /* for load-balancing */
struct rb_node run_node;
struct list_head group_node;
unsigned int on_rq;
u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;
u64 prev_sum_exec_runtime;
u64 nr_migrations;
#ifdef CONFIG_SCHEDSTATS
struct sched_statistics statistics;
#endif
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_entity *parent;
/* rq on which this entity is (to be) queued: */
struct cfs_rq *cfs_rq;
/* rq "owned" by this entity/group: */
struct cfs_rq *my_q;
#endif
};
和RT(实时)实体是
struct sched_rt_entity {
struct list_head run_list;
unsigned long timeout;
unsigned int time_slice;
struct sched_rt_entity *back;
#ifdef CONFIG_RT_GROUP_SCHED
struct sched_rt_entity *parent;
/* rq on which this entity is (to be) queued: */
struct rt_rq *rt_rq;
/* rq "owned" by this entity/group: */
struct rt_rq *my_q;
#endif
};
这两个都使用list_head
./include/linux/types.h
结构
struct list_head {
struct list_head *next, *prev;
};
老实说,我不明白将如何安排这样的事情。任何人都可以解释这是如何工作的。
。P.S :
此外,我真的很难理解数据成员名称的含义。任何人都可以建议一个良好的阅读理解内核结构,以便我可以轻松地弄清楚这些事情。我花费的大部分时间都浪费在搜索数据成员的含义上。
答案 0 :(得分:2)
为了实现组调度,引入了调度实体,这样CFS(或RT调度程序)将为各个任务提供公平的CPU时间,同时为单个任务组提供合理的CPU时间。调度实体可以是任务或任务组。
struct list_head
只是实现链表的Linux方式。在您发布的代码group_node
和run_list
中,您可以创建struct sched_entity
和struct sched_rt_entity
的列表。可以找到更多信息here。
使用这些list_heads
调度实体存储在某些与调度程序相关的数据结构中,例如cfs_rq.cfs_tasks
如果实体是使用account_entity_enqueue()
排队的任务。
始终可以在其源代码中找到Linux内核的最新文档。在这种情况下,您应该检查this目录,特别是this文件,其中描述了CFS。还有an explanation个任务组。
编辑: task_struct
包含se
类型的字段struct sched_entity
。然后,使用sched_entity
宏为container_of
对象提供地址,可以检索task_struct
对象的地址,请参阅task_of()
。 (sched_entity
对象的地址 - se
中task_struct
的偏移量= task_struct
对象的地址)这是我在前面提到的列表实现中常用的一种技巧答案。