网络宝典
第二套高阶模板 · 更大气的阅读体验

线程调度机制:CPU是怎么决定先跑哪个线程的?

发布时间:2026-03-28 16:31:45 阅读:1 次

你打开浏览器刷网页,后台还挂着微信、音乐播放器、下载工具——这些程序看似同时运行,其实 CPU 每个时刻只真正执行一个线程。那它凭什么让微信弹出消息不卡顿,又不让下载任务彻底抢光资源?答案就藏在线程调度机制里。

调度不是“随机点名”,而是有章法的排队

操作系统内核里有个叫“调度器”的小管家,它盯着所有就绪态的线程(即已准备好、只等 CPU 的线程),按策略挑下一个上 CPU 的。常见策略有几种:

  • 时间片轮转(RR):每个线程分到一小段固定时间(比如 10ms),用完就强制让出 CPU,排到队尾再等下一轮。就像食堂打饭,每人打一勺,打完回队尾继续等,保证人人有份。
  • 优先级调度:给线程标个“紧急程度”,比如鼠标点击响应线程优先级高,视频解码线程中等,日志写入线程低。高优线程来了,当前低优线程可能被立刻打断。
  • 多级反馈队列(MLFQ):Linux 默认用的变种。新线程先进高优先级队列,用完时间片就降一级;如果它老是主动让出 CPU(比如等网络数据),说明是交互型任务,反而会被提级——这样既照顾响应速度,也不饿死后台计算任务。

举个真·日常例子

你边用微信语音通话,边用迅雷下载大文件。语音线程被标记为实时(SCHED_FIFO),优先级拉满;下载线程走的是普通 CFS(完全公平调度器)策略,按权重分时间。哪怕下载占满磁盘和网卡,语音线程也能在毫秒级内抢到 CPU,保证你说“喂?听得到吗?”对方不会等到三秒后才反应过来。

代码里也能看见调度痕迹

在 Linux 下,可以用 chrt 命令手动调整进程调度策略。比如启动一个高优循环任务:

chrt -f 50 sh -c 'while true; do echo "running"; sleep 0.1; done'

其中 -f 表示 FIFO 策略,50 是优先级数值(1–99,越高越霸道)。这时候如果再跑一个普通 sleep 进程,它大概率会被这个高优任务压得几乎没机会执行。

别忘了:调度机制不是万能的

它管的是“谁上 CPU”,但线程卡顿还可能因为等锁、等磁盘、等网络包——这些都不归调度器管。就像机场值机柜台排着队,调度器只决定下一个谁去柜台,但如果你的护照落在家里,再快的排队也没用。

所以看到程序“假死”,先别急着怪调度器,看看是不是在等 I/O、是不是锁住不动了、或者内存爆了被 OOM Killer 干掉了。