现代 Linux 是一个强占多任务系统,调度器负责决定哪个进程在何时使用 CPU。优先级、时间片和抢占机制,是调度器实现公平和响应速度的三个核心要素。
1. 优先级:谁先运行,谁分得更多
Linux 使用动态优先级来决定进程的重要性。每个进程都有一个 nice 值(范围 -20 到 19),数值越低,优先级越高,就能获得更多的 CPU 时间。普通用户只能调高自己进程的 nice 值(表示谦让),只有 root 才能调低(表示抢占)。
除了 nice 值,调度器内部还会维护一个更细的动态优先级,它会随着进程的睡眠、I/O 等待、已经消耗的 CPU 时间等因素实时调整。一个已经长时间霸占 CPU 的计算密集型进程,其动态优先级会被逐渐降低,为交互式进程(如桌面程序、数据库响应线程)让路,保证用户能感受到系统的流畅。
2. 时间片:一次能跑多久
时间片是一个进程在被迫让出 CPU 之前允许连续运行的最大时长。在 Linux 的完全公平调度器(CFS,默认调度器)里,时间片并非一个固定的毫秒值,而是根据系统中的可运行进程数动态计算。调度器会给每个进程分配一个“虚拟运行时间”额度,物理时间片等于这个额度乘以当前运行进程数的倒数。
这样设计的目的是维护公平性:无论有多少进程在竞争 CPU,每个进程得到的“虚拟时间”进度是公平的。当你运行 top 或 htop 时,看到 %CPU 基本均分的情况,背后就是 CFS 在尽力保证每个进程都获得它应得的 CPU 份额。
3. 抢占机制:紧急任务无需等待
抢占允许调度器强制暂停一个正在运行的进程,把 CPU 转交给更重要的新任务。Linux 支持用户态抢占(进程在用户空间执行时可以被抢占)和内核态抢占(配置 CONFIG_PREEMPT 后,大部分内核代码路径也允许抢占)。
典型的场景是:一个后台计算程序正在跑满 CPU,你按下一个键盘按键,内核的中断处理触发了 GUI 进程的唤醒。调度器发现刚唤醒的 GUI 进程有更高的动态优先级,便立刻抢占当前的低优先级计算进程,让 GUI 立即响应你的操作。这种机制使得 Linux 的桌面和服务器都可以同时兼顾高吞吐量和低延迟。
在实际运维和开发中,你可以用 nice 和 renice 命令调整进程优先级,用 chrt 改变实时调度策略,或者在编译内核时根据场景选择不同的抢占模型(服务器选 no forced preemption,桌面选 voluntary 或 preemptible)。理解这三个机制,能帮助你诊断 CPU 占用不均、界面卡顿或实时任务延时过高等问题。