Linux进程调度机制笔记

1 Linux任务调度基本概念

1.1 task_struct

  Linux系统上执行很多进程、线程,但在内核中这些都被称为“任务”,而内核调度的单位也是“任务”,即线程。

  进程和线程的差别在于进程有单独的内存,而线程要和其他线程共享内存。一个进程可以包含很多个线程,所以进程可以理解为线程组。内核代码task_struct结构体里面,刚好有个线程组号tgid。当task_struct中pid与tgid相等时,那么这个线程/任务就是线程组的主线程,即进程号。

  进程号和线程号变量在task_struct结构体内,源码在sched.h中,如下图:

  

  注意,在Linux系统用户态,终端输入ps显示的pid是进程号,用户态的pthread提供了pthread_t来表示线程号,和内核是不同的。

1.2 cpu工作流程

  cpu其实只做两件事:读指令和执行指令。

  while(1){

    读指令;

    执行指令;

  }

  如上是cpu的工作流程,“指令”可以理解成一条条汇编语句。

1.3 任务响应时间和周转时间

  响应时间:从任务到达到任务开始执行的时间;

  周转时间:从任务达到到任务执行完成的时间;

  由以上,不难理解平均响应时间就是所有任务的响应时间总和的平均值,平均周转时间就是所有任务的周转时间总和的平均值,这2个值不能兼得,因此操作系统调度机制重要的就是找到这2者的平衡点。

  想象一下,操作系统同时收到2个任务,一个任务A只需要10s,一个任务B却需要100s,那么为了减小总等待时间,当然应该让A先执行;可是如果这个时候又来了个任务C,需要2s就能完成,又让B继续等待,这样B可能会一直等待;那么如果按先来后到处理,让B执行10s完成后,C再执行,这样C就要等待10s等待时间太长了;那么如果轮询处理,每个任务处理1s,然后处理下个任务,这样的话每个任务等待时间都少,但是频繁的切换任务,整个效率就下降了;又或者有个任务等级很高,要优先处理。。。基于不同的场景和效率评估,有了不同的调度策略

  注:下文代码基于Linux 5.10.1版本查看。

 

2 调度策略的实现

  上文我们已经知道Linux对进程会采取不同的调度策略,每一种调度策略都有对于的调度类来实现具体算法,在include/linux/sched.h中,又如下图:

  

  上图罗列了Linux内核支持的调度类。

2.1 公平调度类

我们具体看各个调度类的实现,先看公平调度类,如下图:

  

  上图是公平调度类的算法实现,他有一个虚拟时间vruntime来记录任务的运行时间,运行时间少的任务会被优先运行,这样就能让所有任务得到相对公平的运行。

  当然,还可以给这些任务添加一个权重,然后根据权重调整虚拟运行时间,这样就能同时满足优先级和公平。

  上图中,我们重点关注update_curr_fair这个函数,他就是更新运行时间的函数,这个函数源码在kernel/sched/fair.c中(说到看代码,电脑卡的同学可以把drivers、tools、Documentation目录暂时挪走,这样代码索引会更快),代码如下图:

  

  这里rq指向的curr是结构体task_struct, se是里面的成员struct sched_entity se; struct sched_entity se是调度实体,这些实体里面记载了虚拟运行时间vruntime。任务的节点又通过红黑树结构进行管理。

  而cfs_rq_of返回的是struct cfs_rq,如下图:

  

  我们再看update_curr就会知道它根据cfs_rq找到sched_entity,然后更新sched_entity中的时间。

  

  我们再看sched_entity结构体源码:

  

  上图中cfs_rq指向了调度队列。每个cpu都有自己的调度队列。这个队列根据不同的调度策略又划分成不同的子队列,各个队列结构体成员中又有成员指向红黑树的根节点。

  那么,调度类如何使用调度实体和调度队列?

  上面公平调度类代码中,我们看到公平调度类中有个成员pick_next_pick,这个函数就算找到下一个要执行的任务。

  __pick_next_task_fair调用到pick_next_task_fair,这个函数从红黑树中找到执行时间最小的任务,然后返回这个任务对于的task_struct.

  那么,什么时候会执行调度呢?有两种情况,主动调度和被动调度,主动调度就是主动调用schedule函数,必然一个任务sleep,就会主动让出cpu;另一个情况是被动调度,就是抢占式调度。

  主动调度很容易理解,下面主要讲解被动调度。

 

  

  

  

  

 

posted @ 2024-11-26 22:47  Riemann$Hypothesis  阅读(28)  评论(0编辑  收藏  举报