← 返回题目列表

队列调度中的公平性和饥饿问题是什么?

中等 第 28 / 30 题 更新于 2026/07/30
队列调度公平性饥饿

简化版

队列公平性指任务能否按合理顺序获得处理机会;饥饿指某些任务长期得不到执行。普通 FIFO 比较公平,但优先级队列、多个队列竞争、锁队列调度都可能让低优先级任务长期等待,需要老化、配额或轮询等策略缓解。

详细版

队列不只是存数据,也常用于调度。调度时除了吞吐,还要考虑公平。

典型问题:

  • FIFO:先到先服务,简单公平,但不能表达紧急任务。
  • 优先级队列:高优先级先执行,但低优先级可能饥饿。
  • 多队列:不同来源任务可能互相挤压。
  • 锁等待队列:非公平锁可能让新来的线程插队。

解决思路包括优先级老化、时间片轮转、加权轮询、最大等待时间和监控等待分布。

完整版教学

一、队列为什么会参与调度

很多系统中,队列决定“谁先被处理”。线程池任务队列、消息消费队列、网络请求队列、锁等待队列,本质上都在做调度。

如果只看数据结构,队列是容器;如果看系统行为,队列是秩序。

任务进入队列 -> 队列规则排序 -> 执行器取任务

规则不同,系统表现完全不同。FIFO、优先级、轮询、多级反馈队列,都是在回答“下一个轮到谁”。

二、FIFO 公平但不总是最优

FIFO 先到先服务,直觉上很公平。先来的任务先处理,后来的任务后处理。

但 FIFO 也有问题。如果队头是一个耗时 10 秒的大任务,后面 100 个耗时 1 毫秒的小任务都要等它。这叫队头阻塞。

[10s任务, 1ms, 1ms, 1ms ...]

所以公平不等于低延迟。调度设计经常要在公平、吞吐、平均延迟和尾延迟之间取舍。

三、优先级队列为什么可能导致饥饿

优先级队列会优先处理高优先级任务。如果高优先级任务源源不断,低优先级任务可能一直排不到。

例如:

每秒进入 100 个高优先级任务
消费者每秒只能处理 100 个任务
低优先级任务永远没有机会

这就是饥饿。它不一定是 bug,而是策略缺陷:系统规则允许某类任务长期没有服务机会。

四、如何缓解饥饿

常见办法是让等待时间影响调度权重。

策略做法适合场景
优先级老化等越久优先级越高防低优先级饥饿
时间片轮转每类任务轮流处理多租户或多来源
加权轮询高权重多处理,低权重也有份不同业务等级
最大等待时间超过阈值强制提升有 SLA 的任务

这些策略的目标不是取消优先级,而是防止优先级把某些任务永久压死。

五、公平锁和非公平锁也是队列问题

锁竞争时,等待线程也可以排队。公平锁倾向按等待顺序唤醒线程;非公平锁允许新来的线程尝试插队。

公平锁减少饥饿,但可能降低吞吐,因为严格排队会增加上下文切换和调度成本。非公平锁吞吐可能更高,但某些线程在极端情况下等待更久。

公平:排队买票
非公平:窗口空了,新来的人也可能抢到

这说明公平性往往不是免费午餐。

六、怎么监控公平性

平均等待时间不够。一个系统平均等待 10ms,也可能有少数任务等了 10 秒。要看分位数、最大等待时间、各优先级队列长度和被拒绝/超时次数。

记忆钩子:队列调度问的不只是“谁在前”,还要问“有没有人永远轮不到”。

七、常见误区与追问

  • 误区:FIFO 一定是最佳公平。 FIFO 简单公平,但可能被慢任务造成队头阻塞。
  • 误区:优先级越高系统越好。 高优先级持续涌入会让低优先级饥饿。
  • 误区:公平策略没有成本。 公平可能牺牲吞吐或增加调度开销。
  • 追问:如何防止低优先级任务饿死? 用老化、配额、加权轮询或最大等待时间。
  • 追问:看平均延迟够吗? 不够,要看分位数和最大等待时间,尤其关注低优先级任务。

八、加强记忆

队列一旦用于调度,就不只是先进先出的小容器,而是资源分配规则。FIFO 简单但可能队头阻塞,优先级灵活但可能饥饿,公平锁稳定但可能牺牲吞吐。回答时抓住“公平、饥饿、代价、监控”四个点。