调度器
这页讲的是:当系统里有很多任务都想运行时,Linux 内核怎么决定谁先用 CPU、谁稍后再运行。学调度器的核心,不是记住某个算法名,而是理解“CPU 时间是一种必须被分配的资源”。
这块是什么
调度器是 Linux 内核最核心的资源分配者之一。程序、线程、内核任务都会争用 CPU,而调度器负责在很多候选者之间做决定。它解决的不是“程序要做什么”,而是“现在谁可以跑”。
把 CPU 想成一间会议室,很多人都想进去发言;调度器就是安排发言顺序和时间的人。
它负责什么
分配 CPU 时间
- 决定哪个任务现在运行
- 决定什么时候切换到别的任务
- 平衡响应性和吞吐量
- 尽量让系统既不拖沓也不失控
处理不同类型任务
- 普通任务
- 实时任务
- 内核线程
- 让不同诉求的任务按不同规则参与竞争
适应多核系统
- 在多个 CPU 之间平衡负载
- 考虑亲和性和缓存局部性
- 避免某些 CPU 过载
- 减少“有的核很闲,有的核很忙”的情况
一个任务为什么会停下来
| 情况 | 你现在怎么理解 | 和调度器的关系 |
|---|
| 时间片用完 | 它已经运行了一段时间,需要给别人机会。 | 体现调度器对公平性和整体响应的管理。 |
| 主动阻塞 | 任务在等 I/O、等锁、等事件,不是它想跑就能跑。 | 调度器要把 CPU 让给当前真正能继续运行的任务。 |
| 更高优先级任务出现 | 有更急或更重要的任务需要立刻响应。 | 体现调度器不是平均主义,而是有层次地分配 CPU。 |
| 负载迁移 | 多核环境里,任务可能被移动到别的 CPU 上。 | 这和负载均衡、亲和性、缓存效果都有关系。 |
关键概念
| 概念 | 现在怎么理解 |
|---|
| 进程 / 线程 | 都是可被调度的执行实体,只是资源共享方式不同。 |
| 上下文切换 | CPU 从一个任务切到另一个任务时,保存和恢复执行现场。 |
| 优先级 | 某些任务比另一些任务更“应该先跑”。 |
| 调度类 | 不同类型任务适用不同调度规则。 |
| 负载均衡 | 多核机器上,把任务合理分布到不同 CPU。 |
为什么重要
- 它决定系统交互是否流畅。
- 它影响吞吐量、延迟和公平性。
- 服务器、桌面、嵌入式设备对调度的要求并不一样。
- 很多“系统卡不卡”“响应快不快”的体感,背后都绕不开调度。
常见误解
- 误解一:调度器只和 CPU 利用率有关。实际上它还深刻影响延迟、交互性和等待体验。
- 误解二:线程多就一定更快。实际上线程越多,调度和切换开销也可能越大。
- 误解三:调度器只在切换进程时才重要。实际上任务等待锁、等待 I/O、处理中断后续工作时,也都和调度环境有关。
它不负责什么
- 它不决定数据放在哪,那是内存管理的事情。
- 它不负责文件怎么读取,那是文件系统和块层的事情。
- 它也不直接处理网络协议内容,但网络路径会受到调度影响。
和其他模块的关系
| 相关模块 | 关系 |
|---|
| 中断 / 定时器 | 很多调度动作与时钟推进和事件触发有关。 |
| 内存管理 | 任务切换和地址空间切换、内存压力等会相互影响。 |
| 并发控制 | 调度与锁密切相关,因为任务可能在等待锁时被切换。 |
| cgroup / 容器 | 资源控制和隔离会影响调度策略和分配结果。 |
你现在最值得先建立的运行画面
| 场景 | 调度器在看什么 | 你先记住哪一点 |
|---|
| 一个任务正在跑 | 它还能不能继续独占 CPU。 | 调度器最先处理的是“现在谁占着 CPU”。 |
| 另一个任务醒了 | 新来的任务是否更值得马上运行。 | 调度不是平均发糖,而是不断重新比较当前局面。 |
| 任务在等锁或 I/O | 它现在并没有资格继续占 CPU。 | 很多“程序变慢”其实不是没活做,而是在等待别的条件。 |
| 多核机器上有的核很忙、有的核很闲 | 要不要迁移任务、迁过去值不值。 | 多核调度的难点不只是分摊数量,还要顾及局部性和迁移成本。 |
读完这页后,你应该能回答
- 调度器解决的核心问题到底是什么?
- 为什么任务并不是“想跑就一直跑”?
- 为什么多核调度不只是把任务随便摊开这么简单?
后面适合继续问:线程和调度实体到底是什么关系?实时任务和普通任务有何本质差别?多核负载均衡为什么难?