1. 并发调度概述
大家好,我是你们的老朋友。今天咱们聊聊并发调度。
说实话,我刚开始做系统开发那会儿,对并发调度这玩意儿完全没概念。那时候写的程序都是单线程的,跑得也挺欢。直到有一次,我接手了一个高并发的Web服务项目——用户量一上来,系统直接卡死。嗯,从那以后,我才真正开始研究调度器是怎么工作的。
什么是并发调度?
并发调度,说白了就是操作系统或者运行时环境,决定「下一个该谁干活」的过程。
你想想看,CPU就那么几个核,但任务可能有成百上千个。谁先执行?谁后执行?谁该被暂停?谁该被唤醒?这些决策,就是调度器干的活。
我个人习惯把调度器想象成一个「交通指挥员」。它站在十字路口,看着四面八方涌来的任务流,然后决定:
- 哪个任务现在可以「绿灯通行」
- 哪个任务需要「红灯等待」
- 哪个任务该走「专用车道」
我在项目中遇到过一种情况:一个任务占着CPU不放,其他任务全在排队。这就是调度策略没设计好。好的调度器,能让每个任务都觉得「CPU好像是我一个人的」。
为什么需要并发调度?
这个问题其实挺有意思。有人会问:让任务自己跑不就行了?干嘛还要调度?
原因有三:
- 资源有限:CPU核数固定,但任务数远超核数。没有调度,大家抢成一团。
- 公平性:每个任务都应该有机会执行。不能一个任务霸占CPU,其他任务饿死。
- 响应速度:用户点击按钮,你总不能让系统等10秒才响应吧?调度器要保证交互任务的及时性。
核心观点:没有调度器的系统,就像没有红绿灯的十字路口——看似自由,实则混乱。
我记得有一次做嵌入式开发,一个传感器采集任务优先级设得太低,结果数据采集跟不上,整个控制逻辑全乱了。后来调整了调度策略,问题才解决。这就是为什么我们需要调度——它决定了系统的「生死时速」。
并发与并行的区别
这个问题,我面试过很多人,十有八九会搞混。咱们今天一次说清楚。
| 概念 | 定义 | 类比 |
|---|---|---|
| 并发 | 多个任务在同一个时间段内交替执行 | 一个人同时做两件事:边吃面边看手机 |
| 并行 | 多个任务在同一个时刻同时执行 | 两个人各做各的事:你吃面,我看手机 |
并发是「逻辑上的同时」,并行是「物理上的同时」。
举个例子:单核CPU上跑多线程,那就是并发——CPU在多个线程间快速切换,看起来像同时运行。多核CPU上跑多线程,那才是真正的并行——每个核同时执行不同的线程。
我曾经犯过一个错误:以为并发数开得越多,性能就越好。结果在单核机器上开了100个线程,上下文切换开销直接把CPU干到100%,业务吞吐量反而下降了。嗯,这就是没搞懂并发和并行的区别。
避坑指南:我曾经在项目里把并发数设成CPU核数的10倍,结果性能惨不忍睹。后来改成核数的2倍,效果反而最好。记住:并发不等于并行,线程数不是越多越好。
调度器的核心目标
调度器不是随便乱调的,它有明确的目标。我总结为四个字:快、公、稳、省。
- 快:响应时间要短。用户点击后,系统要尽快给出反馈。
- 公:公平性。每个任务都有机会执行,不能有任务被「饿死」。
- 稳:吞吐量要稳定。不能一会儿快一会儿慢,系统要可预测。
- 省:资源利用率要高。CPU、内存、IO都要充分利用,不能浪费。
这四个目标之间,其实是有冲突的。比如:要响应快,就得让交互任务优先执行,但这可能会影响后台任务的公平性。调度器就是在这些目标之间找平衡。
我个人习惯用一张图来理解调度器的核心逻辑:
这张图展示了调度器的核心流程:任务从队列出发,经过调度策略的决策,最终分配到CPU核心上执行。执行结果会反馈回来,影响后续的调度决策。而所有的决策,都围绕着「快、公、稳、省」这四个目标。
注意:调度器的设计没有银弹。不同的应用场景,侧重点完全不同。比如:
- 实时系统:优先保证「快」,响应时间必须可控
- 批处理系统:优先保证「稳」,吞吐量最大化
- 桌面系统:优先保证「公」,不能让某个应用卡死
好了,这一章的内容就到这里。调度器这东西,说简单也简单,说复杂也复杂。但只要你理解了它的核心目标——快、公、稳、省——再去看各种调度算法,就会发现万变不离其宗。
下一章,咱们聊聊具体的调度算法,看看那些经典的调度策略到底是怎么工作的。
一句话总结:并发调度就是「谁先谁后」的艺术,调度器就是那个「交通指挥员」。