多任务

非抢占式多任务 (cooperative)

  • yielding 来挂起自己 - 让步

抢占式 (preemptive)

  • 由调度程序来决定执行时间
  • 强制挂起即为抢占
  • timeslice - 处理器时间段

策略

I/O 消耗型进程

  • 大部分时间用于提交 I/O 请求或等待 I/O 请求
  • 经常可运行(但运行时间短)
  • 因为在等待 I/O 时总阻塞(I/O 为可阻塞资源,比如键盘输入或网络 I/O)

处理器消耗型进程

  • 把时间大多用于执行代码
  • 除非被抢占否则一直运行
  • 调度策略尽量降低它们的调度频率以延长其运行时间

进程优先级

  • 通过 nice 值(-20 ~ +19),nice 值越大优先级越低
  • 实时优先级(0 ~ 99),越大优先级越高

时间片

调度算法

调度器类 (schedule classes)

  • 按照优先级遍历,比如 CFS

完全公平调度 CFS

时间记账

  • 类似于 Unix 下的 timeslice 通过系统节拍自减到零则挂起

调度器的实体结构

uploading-image-987678.png
uploading-image-989243.png

  • 虚拟实时,与定时器节拍不再相关,以 ns 为单位

  • 使用 vruntime 变量来记录

  • 传入就绪队列Cfs_rq

  • 获取当前运行的任务(调度实体)curr

  • 获取当前的运行时间 now

  • if (unlikely(!curr)) 即:如果 (curr == null 的概率较低)

  • 得到这次实际运行的时间 delta_exec(exec_start 是该任务上一次开始运行的时间节点)

  • 如果运行时间存在,则还需要更新 exec_start 为本次运行的结束时间(即下次运行的开始)

  • 取出该进程的任务结构体指针 *curtask,调用各种辅助统计接口