操作系统

时钟中断与上下文切换:多个程序为什么能“同时”运行

一个 CPU 核心同一时刻只能跑一个程序,Linux 靠快速轮换制造“同时运行”的效果。

概况

以一个 CPU 核心上轮流运行两个程序为例。

一句话总结
时钟定期打断程序,内核保存现场、换另一个程序上场
为什么需要时钟
程序不会自愿让出 CPU,必须有外力把控制权拿回内核
Linux 调度器
长期用 CFS(完全公平调度),6.6 版起换成 EEVDF
代价
切换要花时间,还会让 CPU 缓存变冷
类比
JS 事件循环靠任务主动让出;操作系统是强制轮换
进程状态
运行、就绪(等 CPU)、阻塞(等 I/O)三态之间转换
抢占
时间片用完或更高优先级任务就绪时,内核强制换人
线程切换
同一进程的线程切换不用换页表,比进程切换便宜

步骤 7 / 7

多核:每个核心各自轮转

有多个核心时,每个核心有自己的运行队列,调度器还要在核心之间搬任务。

多核上,几个程序是真的同时在跑,但每个核心内部仍然在分时轮换。 Linux 给每个核心一条运行队列,忙的核心会把任务“分”给闲的核心(负载均衡)。 但任务搬到别的核心后,原来缓存里的数据用不上了,所以调度器倾向让任务留在原核心(亲和性),taskset 可以手动指定。

程序
内核
硬件
程序 A
程序 B
内核(调度器)
CPU 与时钟
核心 0 的任务迁到核心 1
事件日志(7)
当前状态发生了什么
A 运行中程序 A 正在使用 CPU
进入内核态时钟到点,CPU 陷入内核
内核态保存程序 A 的上下文
内核态调度器选中程序 B
调度按策略挑选下一个
B 运行中切回用户态,程序 B 继续运行
负载均衡在核心间迁移任务