1.2. 上下文切换:__schedule()

Posted broler

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.2. 上下文切换:__schedule()相关的知识,希望对你有一定的参考价值。

上下文的切换时机

调度的核心代码位于kernel/sched/core.c中,调度算法的运行并没有单独调度线程,而是将调度器在很多个内核逻辑点埋点调用。调度系统的主要入口函数是__schedule()函数,以下画线开头是因为在这个函数基础上封装了不同情况下的一系列函数入口,但是主体的进入逻辑都是__schedule()函数。在进入这个函数之前一定要关闭抢占,该函数是整个调度模块最核心的位置。

调度器可以通过定时器触发,周期性地运行,与渲染的每一帧都进行状态变换和处理类似,调度器也需要在每一帧(HZ)都更新内部的参数,并且决定当前的调度是否要发生变化。例如一个调度器认为一个进程的时间片用尽,就会通过设置该进程的TIF_NEED_RESCHED标志,使得这个进程在系统调用或者中断返回的时候触发重新调度。在周期性的定时器调度逻辑运行的过程中,不调用__schedule()函数来真实地发生调度,只是更新调度器的状态,调用__schedule()函数进行实际的任务切换的是在系统调用或者中断返回时的用户线程上下文中发生的。

如果只有上述的周期性调度运行,并且只依赖系统调用返回和中断返回的逻辑进行判断,则很容易导致内核调度长时间地不工作,尤其在HZ的值配置的较小的情况下。因为虽然调度器在进行周期性的工作,但是周期性的工作并不直接让一个进程停止运行,并出让CPU给其他的线程,而是通过设置标志来通知目标进程。在目标进程返回用户空间时再检查,再主动进入调度逻辑来出让CPU。如果一个系统调用在内核中的执行时间过长,或者可能在内核的路径中阻塞,就会导致调度器的指令长期无法得到响应,所以一个内核进程就需要更多的点来主动调用__schedule()函数。

内核路径中可能阻塞的一系列功能(例如互斥锁、信号量、等待队列等&#

以上是关于1.2. 上下文切换:__schedule()的主要内容,如果未能解决你的问题,请参考以下文章

linux内核—进程调度(核心)

Linux性能学习(1.4):CPU_如何查看CPU上下文切换参数

Linux性能学习(1.4):CPU_如何查看CPU上下文切换参数

Linux性能学习(1.4):CPU_如何查看CPU上下文切换参数

018_异步_Schedule

schedule()函数详解