1. 简介

进程是资源管理的单位
线程是 cpu 调度的单位
内核中调度的是一个 task 的结构, 我们可以称之为任务
任务调度的目的主要是以下三点

  1. 尽量公平的调度所有任务
  2. 提高系统吞吐量
  3. 提高系统响应速度

任务

普通任务

交互式任务, 需要响应快
批处理任务, 需要吞吐量高

实时任务, 需要响应快

同时所有任务都要兼顾尽量公平
时间片过大, 响应就会变慢, 时间片过小, cpu 就会忙于任务切换, 吞吐量就会下降
所以需要一个正正好的策略


2. 2.4内核时代

任务的切换分两种

任务等待某些资源无法继续执行, 主动让出 cpu
cpu 时间片被用完, 被抢占

三种策略

普通, 时间片轮转, 先到先得
所有待调度的 task 都在一个队列 runqueue 中, 谁的动态优先级最高, 谁就优先执行
task 创建的时候固定静态优先级, 调度过程按动态优先级, 动态优先级根据静态优先级和时间片剩余共同计算得出
实时 task 动态优先级肯定大于普通 task
普通 task 若时间片耗尽, 那动态优先级设为0, 此次调度循环不会再调度
普通 task 睡眠时间越多, 越容易被调度

调度时机

进程主动发起调度 timer 中断处理过程中发现当前 task 耗尽时间片 进程唤醒的过程中 父进程创建子进程的时候 进程切换的时候 task 主动让出 cpu 用户进程主动修改调度参数

主调度

遍历 runqueue, 计算动态优先级, 最高的那个进行调度, 复杂度 O(n) 每个 task 根据静态优先级分配一个初始时间片, 静态优先级越大, 时间片越大 task 被调度执行后, 时间片会递减, 耗尽之后, 本轮调度将不会在调度该 task runqueue 中所有 task 时间片都被消耗完后, 本轮调度结束


3. 2.6 内核时代

对 2.4 的调度进行了改进, 将全局 runqueue 分散到每个 cpu 上, 每个 cpu 下面都有一个 runqueue
调度系统首先对 task 进行负载均衡, 将 task 分到不同的 per-cpu-runqueue 上 per-cpu-runqueue 分别维护 active task 队列和 expired task 队列, 每次调度只选取 active task 队列里的 task
调度完之后, 把 active 指向 expired 即可 其他优先级策略改动不大