任务模型:周期性任务、偶发任务、非周期性任务与任务参数

聊到实时调度,第一个绕不开的话题就是任务模型。说白了,你得先搞清楚你的任务长什么样,才能谈怎么调度它。我这些年调过的系统里,十有八九的性能问题,根源都在于一开始对任务模型的理解不够透彻。

任务模型定义了任务的到达模式、执行时间特征和时序约束。这是调度算法的输入,也是性能分析的起点。你想想看,连任务是什么类型都没搞清,调度策略再花哨也是白搭。

一、周期性任务

周期性任务是最常见的模型。任务每隔固定的时间间隔释放一次,周而复始。比如传感器数据采集、控制回路计算、心跳检测,都属于这一类。

它的核心特征就三个:

  • 固定周期 T:相邻两次释放的时间间隔恒定
  • 固定执行时间:每次执行所需的CPU时间基本一致
  • 硬截止时间:通常要求在下一个周期开始前完成

我在项目中遇到过这样一个场景:一个工业控制系统的采样任务,周期是10ms,但偶尔会因为中断处理导致执行时间抖动。嗯,这里要注意——周期性任务并不意味着每次执行时间完全一样,而是说它的释放模式是周期的。

关键点:周期性任务的利用率计算公式为 U = C/T,其中C是WCET,T是周期。所有周期性任务的总利用率不能超过调度算法的可调度性上界。

二、偶发任务

偶发任务,也叫零星任务。它和周期性任务很像,但有一个关键区别:两次释放之间的最小时间间隔是固定的,但实际间隔可以更长

举个例子:一个报警处理任务,系统要求两次报警处理之间至少间隔100ms。但报警可能几秒才来一次,也可能一天都不来。这就是典型的偶发任务。

我个人习惯把偶发任务看作是「有最小间隔约束的周期性任务」。调度分析时,我们通常用它的最小到达间隔来替代周期,这样就能复用周期性任务的调度分析方法。

避坑指南:我曾经把一个偶发任务当成周期性任务来处理,结果在压力测试时系统直接崩溃。原因很简单——偶发任务的释放间隔虽然最小是固定的,但可能连续密集到达,导致瞬时负载飙升。所以,偶发任务的WCET分析一定要考虑最坏情况下的背靠背到达模式。

三、非周期性任务

非周期性任务,也叫异步任务。它的释放时间完全不可预测,没有周期约束,也没有最小间隔约束。用户按键响应、网络数据包处理、外部事件触发,都属于这一类。

非周期性任务通常分为两种:

  • 软实时任务:错过截止时间会降低服务质量,但不会造成灾难性后果
  • 硬实时任务:错过截止时间可能导致系统失效

你想想看,非周期性任务的调度难点在哪?就在于你不知道它什么时候来,也不知道一次来多少。我见过一个系统,平时负载只有30%,但突发网络风暴时,非周期性任务瞬间把CPU占满,导致周期性任务全部超时。

处理非周期性任务,常用的手段是给它分配一个后台服务器任务,或者用轮询服务器、优先级继承等机制来隔离它对周期性任务的影响。

四、任务参数详解

每个任务都有一组关键参数,这些参数是调度分析和性能调优的基础。我列个表,方便你对照查看:

参数 全称 含义 典型取值
WCET 最坏情况执行时间 任务在所有可能情况下执行时间的最大值 通过静态分析或测量获得
BCET 最好情况执行时间 任务在所有可能情况下执行时间的最小值 通常用于分析资源释放时机
T 周期/最小到达间隔 周期性任务的固定周期,或偶发任务的最小到达间隔 由系统需求决定
D 截止时间 任务必须完成的时间点 通常 D ≤ T,但也有 D > T 的情况

4.1 WCET 的坑

WCET 是调度分析中最关键也最容易出错的参数。为什么?因为实际执行时间受太多因素影响:

  • CPU 缓存命中/未命中
  • 分支预测成功/失败
  • 内存访问延迟
  • 中断抢占
  • DMA 竞争

我曾经在一个项目中,静态分析出来的 WCET 是 50μs,但实际跑起来偶尔会飙到 200μs。查了半天,发现是某个循环在特定输入下触发了大量的 cache miss。所以,WCET 的确定一定要结合静态分析和实际测量,不能只看理论值。

警告:千万不要用平均执行时间代替 WCET 来做调度分析。平均执行时间只能用于性能评估,不能用于可调度性验证。否则,系统在极端情况下一定会出问题。

4.2 截止时间的分类

截止时间 D 和周期 T 的关系,决定了任务的实时性要求等级:

  • D = T:最常见的约束,任务必须在下一个周期开始前完成
  • D < T:更严格的约束,任务必须在周期内提前完成
  • D > T:允许任务跨越周期边界,但会增加调度分析的复杂度

我个人建议,除非有明确的业务需求,否则尽量保持 D ≤ T。D > T 的情况虽然存在,但调度分析会变得非常复杂,而且容易引入优先级反转等问题。

五、知识体系结构图

下面这张图梳理了任务模型的核心知识结构,方便你建立整体认知:

任务模型知识体系 任务类型 周期性任务 偶发任务 非周期性任务 任务参数 WCET BCET 周期 T 截止时间 D 调度分析 可调度性分析 利用率计算 响应时间分析 任务类型决定释放模式,任务参数决定约束条件 两者共同构成调度分析的输入

六、实际调优中的经验

说了这么多理论,最后分享几个我在实际调优中总结的经验:

  1. 先分类,后调参:拿到一个系统,先花时间把每个任务归类。周期性、偶发、非周期性,分清楚再动手。我见过有人上来就调优先级,结果发现任务类型都搞错了。
  2. WCET 留余量:静态分析出来的 WCET 通常偏乐观,实际测量出来的又可能偏悲观。我个人习惯在两者之间取一个值,再额外加 20% 的余量。
  3. 关注偶发任务的背靠背到达:这是最容易出问题的地方。偶发任务的最小间隔约束只在正常情况有效,极端情况下可能连续到达,一定要做压力测试验证。
  4. 非周期性任务要隔离:用服务器任务或轮询机制把非周期性任务和周期性任务隔离开,避免突发负载影响实时任务的调度。
小技巧:在系统设计阶段,可以用一张表格把每个任务的类型、WCET、BCET、周期、截止时间都列出来。然后计算总利用率,看看是否超过调度算法的理论上限。这一步做扎实了,后面能省很多调试时间。

任务模型是实时系统的基石。把这块吃透了,后面的调度算法分析、性能调优才能有的放矢。嗯,今天就先聊到这,下一节我们深入具体的调度算法。


专注资料整理