1. 并发调度概述

大家好,我是你们的老朋友。今天咱们聊聊并发调度。

说实话,我刚开始做系统开发那会儿,对并发调度这玩意儿完全没概念。那时候写的程序都是单线程的,跑得也挺欢。直到有一次,我接手了一个高并发的Web服务项目——用户量一上来,系统直接卡死。嗯,从那以后,我才真正开始研究调度器是怎么工作的。

什么是并发调度?

并发调度,说白了就是操作系统或者运行时环境,决定「下一个该谁干活」的过程。

你想想看,CPU就那么几个核,但任务可能有成百上千个。谁先执行?谁后执行?谁该被暂停?谁该被唤醒?这些决策,就是调度器干的活。

我个人习惯把调度器想象成一个「交通指挥员」。它站在十字路口,看着四面八方涌来的任务流,然后决定:

  • 哪个任务现在可以「绿灯通行」
  • 哪个任务需要「红灯等待」
  • 哪个任务该走「专用车道」

我在项目中遇到过一种情况:一个任务占着CPU不放,其他任务全在排队。这就是调度策略没设计好。好的调度器,能让每个任务都觉得「CPU好像是我一个人的」。

为什么需要并发调度?

这个问题其实挺有意思。有人会问:让任务自己跑不就行了?干嘛还要调度?

原因有三:

  1. 资源有限:CPU核数固定,但任务数远超核数。没有调度,大家抢成一团。
  2. 公平性:每个任务都应该有机会执行。不能一个任务霸占CPU,其他任务饿死。
  3. 响应速度:用户点击按钮,你总不能让系统等10秒才响应吧?调度器要保证交互任务的及时性。

核心观点:没有调度器的系统,就像没有红绿灯的十字路口——看似自由,实则混乱。

我记得有一次做嵌入式开发,一个传感器采集任务优先级设得太低,结果数据采集跟不上,整个控制逻辑全乱了。后来调整了调度策略,问题才解决。这就是为什么我们需要调度——它决定了系统的「生死时速」。

并发与并行的区别

这个问题,我面试过很多人,十有八九会搞混。咱们今天一次说清楚。

概念 定义 类比
并发 多个任务在同一个时间段内交替执行 一个人同时做两件事:边吃面边看手机
并行 多个任务在同一个时刻同时执行 两个人各做各的事:你吃面,我看手机

并发是「逻辑上的同时」,并行是「物理上的同时」。

举个例子:单核CPU上跑多线程,那就是并发——CPU在多个线程间快速切换,看起来像同时运行。多核CPU上跑多线程,那才是真正的并行——每个核同时执行不同的线程。

我曾经犯过一个错误:以为并发数开得越多,性能就越好。结果在单核机器上开了100个线程,上下文切换开销直接把CPU干到100%,业务吞吐量反而下降了。嗯,这就是没搞懂并发和并行的区别。

避坑指南:我曾经在项目里把并发数设成CPU核数的10倍,结果性能惨不忍睹。后来改成核数的2倍,效果反而最好。记住:并发不等于并行,线程数不是越多越好。

调度器的核心目标

调度器不是随便乱调的,它有明确的目标。我总结为四个字:快、公、稳、省。

  • 快:响应时间要短。用户点击后,系统要尽快给出反馈。
  • 公:公平性。每个任务都有机会执行,不能有任务被「饿死」。
  • 稳:吞吐量要稳定。不能一会儿快一会儿慢,系统要可预测。
  • 省:资源利用率要高。CPU、内存、IO都要充分利用,不能浪费。

这四个目标之间,其实是有冲突的。比如:要响应快,就得让交互任务优先执行,但这可能会影响后台任务的公平性。调度器就是在这些目标之间找平衡。

我个人习惯用一张图来理解调度器的核心逻辑:

调度器核心逻辑框架 任务队列 (就绪任务集合) 调度策略 (优先级/时间片/公平) CPU核心 (执行单元) 反馈:任务完成/阻塞/优先级变化 核心目标:快 · 公 · 稳 · 省 响应时间短 | 公平调度 | 吞吐稳定 | 资源高效

这张图展示了调度器的核心流程:任务从队列出发,经过调度策略的决策,最终分配到CPU核心上执行。执行结果会反馈回来,影响后续的调度决策。而所有的决策,都围绕着「快、公、稳、省」这四个目标。

注意:调度器的设计没有银弹。不同的应用场景,侧重点完全不同。比如:

  • 实时系统:优先保证「快」,响应时间必须可控
  • 批处理系统:优先保证「稳」,吞吐量最大化
  • 桌面系统:优先保证「公」,不能让某个应用卡死

好了,这一章的内容就到这里。调度器这东西,说简单也简单,说复杂也复杂。但只要你理解了它的核心目标——快、公、稳、省——再去看各种调度算法,就会发现万变不离其宗。

下一章,咱们聊聊具体的调度算法,看看那些经典的调度策略到底是怎么工作的。

一句话总结:并发调度就是「谁先谁后」的艺术,调度器就是那个「交通指挥员」。