本次分析的kernel代码为2.6.32-220。并且我们先不考虑SMP。当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为核心调度器);并且每个调度器包括两个内容:调度框架(其实质就是两个函数框架)及调度器类。调度器类是实现了不同调度策略的实例,如 CFS、RT class。它们的关系如下图:
当前的内核支持两种调度器类(sched_setscheduler系统调用可修改进程的策略):CFS(公平)、RT(实时);5种调度策略:SCHED_NORAML(最常见的策略)、SCHED_BATCH(除了不能抢占外与常规任务一样,允许任务运行更长时间,更好地使用高速缓存,适合于成批处理的工作)、SCHED_IDLE(它甚至比nice 19还有弱,为了避免优先级反转使用)和SCHED_RR(循环调度,拥有时间片,结束后放在队列末)、SCHED_FIFO(没有时间片,可以运行任意长的时间);其中前面三种策略使用的是cfs调度器类,后面两种使用rt调度器类。
另外,对于调度框架及调度器类,它们都有自己管理的运行队列,调度框架只识别rq(其实它也不能算是运行队列),而对于cfs调度器类它的运行队列则是cfs_rq(内部使用红黑树组织调度实体),实时rt的运行队列则为rt_rq(内部使用优先级bitmap+双向链表组织调度实体)。下图调度器相关的几个数据结构的关系: