linux调度

调度的基本数据结构

1.每个cpu都有自己的一个struct rq, 里面有一个实时进程的struct rt_rq 和一个普通进程的struct cfs_rq。 在调度时,调度器首先会先去实时进程队列找是否有实时进程需要运行,如果没有才去CFS运行队列找是否有进程需要运行。

2.普遍进程的cfs_rq 定义如下

这里面的rb_root指向的就是红黑树的根节点,这个红黑树在CPU看起来就是一个队列,不断的取下一个应该运行的进程。

rb_leftmost指向的是最左面的节点

3.调度队列——红黑树,调度实体

完全公平调度算法CFS,CFS会为每一个进程安排一个虚拟运行时间vruntime。如果一个进程在运行,随着时间的增长,进程的vruntime将不断增大,但没有得到执行的进行vruntime将不变。

显然,那些vruntime少的,原来受到了不公平的对待,需要给它补上,所以会优先运行这样的进程。

高低优先级怎么处理?优先级其实就是一个数值,对于实时进程,优先级的范围是0-99;对于普通进程,优先级的范围是100-139.数值越小,优先级越高。

在计算vruntime的时候有一个公式

权重和nice数值有关系,nice越小权重就越大, NICE_0_LOAD是nice为0时的权重。所以从这个公式我们可以看出,高优先级(即nice值小的)的进程vruntime加的会少,这就保证了高优先级的进程会优先调度。

看来CFS需要一个数据结构来对vruntime进行排序,找出最小的那个。这个能够排序的数据结构不但需要查询的时候,能够快速找到最小的,更新的时候也需要能够快速的调整排序,要知道vruntime可是经常在变的,变了再插入这个数据结构,就需要重新排序。能够平衡查询和更新速度的是树,在这里使用的是红黑树。

4.调度实体结构

有树就会有节点,有节点就会有对应的数据结构

在task_struct中有这样的成员变量

struct sched_entity se;  完全公平算法调度实体

struct sched_rt_entity rt; 实时调度实体

struct sched_dl_entity dl; Deadline调度实体

进程根据自己是实时的,还是普通的类型,通过成员变量,将自己挂在某一个数据结构里面,和其他的进程排序,等待被调度。如果这个进程是个普通进行,则通过sched_entity,将自己挂在这棵红黑树上。

 5.调度类是如何工作的

每个CPU上都有一个队列rq,这个队列里面包含多个子队列,例如rt_rq和cfs_rq,不同的队列有不同的实现方式,cfs_rq就是用红黑树实现的。

当有一天,某个cpu需要找下一个任务执行的时候,会按照优先级依次调用调度类,不同的调度类操作不同的队列。当然rt_sched_class先被调用,它会在rt_rq上找下一个任务,只有找不到时候,才轮到fair_sched_class调用,它会在cfs_rq上找一个任务。这样保证了实时任务的优先级永远大于普通任务。

上下文切换:

抢占式调度

发布了47 篇原创文章 · 获赞 39 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_28119741/article/details/104407747