调度

介绍调度相关原理和实现

调度

调度术语

术语辨析

  • 被操作系统调度的是内核线程————而不是进程
  • 然而,“线程调度”和“进程调度”这两个属于经常互换使用
  • 当讨论一般概念时我们使用“进程调度”,当设计线程特定概念时使用“线程调度”
  • 同时“在CPU上运行”实际是指在“CPU核心上运行”

注:CPU与CPU核心

  • CPU可以包含多个核心。何以把CPU比作一座办公大楼,CPU核心是一个办公室,正在执行的线程就是一个正在工作的员工

进程调度

基本概念

  • 进程执行由CPU执行和I/O等待的循环组成
  • CPU突发和I/O突发交替进行
  • CPU突发分布在进程间和计算机间差异很大,但遵循相似的曲线
  • 通过多道程序设计获得最大的CPU利用率
  • 当前进程处于I/O突发时,CPU调度器选择另一个进程

CPU调度器

调度决策选择

  • CPU调度器从就绪队列中的进程中进行选择,并将CPU分配给其中一个进程
  • CPU调度决策可能在一下情况发生
    • 进程从运行状态切换到等待状态
    • 进程从运行状态切换到就绪状态
    • 进程从等待状态切换到就绪状态
    • 进程终止
  • 仅在条件1和4下的调度是非抢占式的
    • 一旦CPU被分配给进程,该进程会保持CPU直到终止或等待I/O
    • 也被称为协作式调度
  • 抢占式调度还会在条件2和3下调度进程
    • 抢占式调度需要硬件支持,如定时器
    • 需要同步原语

注:协作式调度与抢占式调度

  • 协作式调度:自觉排队
    • 基本思想:没有管理员的机房,每个人用完电脑后主动让给下一个人,程序自己决定什么时候停下来并主动分享资源
    • 什么时候让出CPU
      • 程序需要读写文件时(I/O)
      • 程序主动调用sleep休眠
      • 程序运行完毕退出
      • 程序主动调用yield让出
  • 抢占式调度:由管理员的排队
    • 核心思想:有管理员的机房,管理员用定时器控制每个人的使用时间,到了时间就必须让出
  • 什么时候强制切换
    • 时间片用完
    • 有更高优先级的程序要运行
    • 程序进行I/O操作时
    • 程序运行完毕

抢占

内核抢占

  • 抢占也会影响系统内核的设计
  • 如果在更新共享数据时被抢占,内核状态将会不一致
  • 即当中断发生时内核正在服务系统调用
  • 两种解决方案
    • 等待系统调用完成或I/O阻塞
    • 内核时非抢占式的,但对进程仍然是抢占式的
    • 在更新共享数据时禁用内核抢占
  • 最新的Linux内核采用这种方法
    • Linux支持SMP
    • 共享数据受内核同步保护
    • 在内核同步时禁用内核抢占
    • 将非抢占式SMP内核转变为抢占式内核

用户抢占和内核抢占的具体时机

  • 用户抢占
    • 从系统调用返回用户空间时
    • 从中断处理程序返回用户空间时
  • 内核抢占
    • 当中断处理程序退出,返回内核空间之前
    • 当内核代码重新变为可抢占时
    • 如果内核中的任务显示调用schedule()
    • 如果内核中的任务阻塞(这会导致调用schedule)

分派器(Dispatcher)

  • 分派器模块将CPU的控制权交给由段齐调度器选中的进程
  • 切换上下文
  • 切换到用户模式
  • 跳转到用户程序中的正确位置以重启该程序
  • 分派延迟:分派其停止一个进程并启动另一个进程所需的时间

调度标准

  • CPU利用率:CPU忙碌的百分比
  • 吞吐量:每个事件单位内完成执行的进程数量
  • 周转时间:执行特定进程的事件
    • 从提交时间到完成时间
  • 等待时间:在就绪队列中等待的总时间
  • 相应时间:从请求提交到产生第一个相应所需的时间
    • 开始相应所需的时间

调度算法优化标准

  • 一般来说,最大化CPU利用率和吞吐率,最小化周转时间、等待时间和响应时间
  • 不同系统优化不同的值
  • 在多数情况下优化平均值
  • 在某些情况下,优化最小值或最大值
    • 例如:实时系统
  • 对于交互式系统,最小化响应时间的方差

调度算法

先来先服务调度(FCFS)

  • 总结:排队买票
  • 核心思想:谁先来谁先服务,就像银行排队一样
  • 工作原理
    • 按照进程到达的先后顺序执行
    • 第一个到达当地的进程先执行完,在执行第二个,以此类推
    • 一旦开始执行就不会被打断
  • 优点:公平、简单、不会饥饿
  • 缺点:短任务可能等很久(护航效应)

最短作业优先调整(SJF)

  • 总结:快餐优先
  • 核心思想:总是先做最快能完成的任务
  • 工作原理:
    • 在所有等待的进程中,选择执行时间最短的执行
    • 可以大幅减少平均等待时间
    • 需要事先知道每个进程要执行多长时间
  • 优点:平均等待时间最短(理论最优)
  • 缺点:长任务可能永远轮不到(饥饿问题)

优先级调度(Priority)

  • 核心思想:重要的任务先做
  • 工作原理:
    • 每个进程都有一个优先级数字
    • 总是选择优先级最高的进程执行
    • 可以根据重要性动态调整优先级
  • 老化机制:为了防止普通顾客永远等不到,可以让等待时间长的客户逐渐升级
  • 优点:体现重要性,灵活可控
  • 缺点:低优先级可能饥饿,需要防饥饿机制

时间片轮转调度(Round Robin)

  • 核心思想:轮流服务
  • 工作原理:
    • 给每个进程分配相同的时间片
    • 时间到了就强制切换到下一个进程
    • 没完成的进程重新排队等下一轮
  • 优点:响应时间好,公平,适合交互式系统
  • 缺点:频繁切换有开销,时间片大小难选择

多级队列调度(MLQ)

  • 核心思想:分类服务
  • 工作原理
    • 把进程分成几个固定的类别(系统进程、前台进程、后台进程等)
    • 每个类别有自己的队列和调度策略
    • 高优先级队列优先服务
  • 优点:不同类型用最适合的策略,系统进程优先
  • 缺点:底层队列可能饥饿,分类可能不准确

多级反馈队列调度(MLFQ)

  • 核心思想:根据客户的行为表现动态调整服务等级
  • 工作原理:
    • 新进程从最高优先级队列开始
    • 如果用完时间片还没完成,就降级到下一级队列
    • 如果主动让出CPU(比如等待I/O),可能提升等级
    • 等待太久的进程会自动升级(防止饥饿)
  • 优点:最只能,自适应,段任务响应快,长任务不饥饿
  • 缺点:最复杂,参数调整困难,实现开销大

MLQ详解

多级队列调度
  • 多级队列调度
    • 就绪队列被分割为多个独立的队列
    • 例如:前台(交互式)进程和后台(批处理)进程
    • 进程被永久分配到指定的队列
    • 每个队列都有自己的调度算法
    • 例如:交互式进程使用RR,批处理进程使用FCFS
  • 队列间调度
    • 必须子啊队列之间进行调度
    • 固定优先级调度
    • 存在饥饿的可能性
    • 时间片分配:每个队列获得一定数量的CPU时间,用于在其进程之间进行调度
    • 例如:前台进程80%时间用RR,后台进程20%时间用FCFS
  • 多级反馈队列
    • 多级反馈队列调度使用多级队列
    • 进程可以在不同队列之间移动
    • 它试图推断进程的类型
    • 老化机制可以通过这种方式实现
    • 目标时给交互式和I/O密集型进程高优先级
  • MLFQ定义参数
    • MLFQ调度器由以下参数定义
    • 队列数量
    • 每个队列的调度算法
    • 确定何时给进程分配更高优先级的方法
    • 确定何时降级进程的方法
    • 确定进程需要服务时进入那个队列的方法
    • MLFQ是最通用的CPU调度算法

线程调度

  • 操作系统内核调度内核线程
  • 系统竞争范围 (SCS):系统中所有线程之间的竞争
  • 内核不知道用户线程的存在
  • 线程库将用户线程调度到LWP上
  • 用于多对一和多对多线程模型
  • 进程竞争范围 (PCS):进程内部的调度竞争
  • PCS通常基于用户设置的优先级
  • 被调度到LWP的用户线程不一定在CPU上运行
  • 操作系统内核需要将LWP的内核线程调度到CPU上
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计