Linux内核中时间片驱动的调度是怎么完成的?
由于近来工作中涉及到调度, 就偶然想出来一个问题: Linux中内核调度CFS是获得task调度的时机的? 是定时更新下每个task的时间片以计算是否需调度? 还是通过让task决定自己主动让出CPU?
Linux中并不区分进程和线程, 而是统一都是Task, 使用struct task_struct
来定义. 这是一个庞大的数据结构. 创建线程和进程时, 根据不同的flag来设置子线/进程与父进/线程是否共享某些数据结构还是通过COW机制来创建新的字段.
在task_struct
中定义了虚拟时间片的概念, 当task的时间片用完以后, 会被调度出CPU, 这个过程是在哪里发生的呢?
首先进程执行的时间片用完这一信息是通过高精度时钟来触发发出的, 计时到期后修改task的时间片信息, 如果发现时间片用完, 则设置TIF_NEED_RESCHED
标志提示可以该task可以被抢占了. 之后某个时刻内核的scheduler相关逻辑被执行时会去检查这个Flag, 并执行schedule(). 被抢占的task可能处于用户态或者内核态(如果允许被抢占).
高精度时钟计时是通过硬件来达到的, 很早期的设计是一个层级时间轮设计, 现在改用了红黑树的设计, 使用事件驱动模式. 这种方式避免了依赖系统硬件的tick来推动时间论运作, 从而提高了精度并模块耦合.
参考: