不必等待任务自愿交还处理器

抢占式调度是一种处理器调度模型,关键是系统可以收回正在运行任务的执行机会,而不必等它结束、阻塞或主动让出。暂停不等于终止:任务的执行状态被保存,日后获调度时可继续。轮转调度、某些优先级调度都可采用抢占,但“抢占”本身不是决定所有运行顺序的完整算法。

与之相比,协作式机制依赖任务在适当时机交还控制。若单个任务一直计算而不合作,其他任务的响应就可能受阻。抢占为操作系统保留重新分配执行机会的手段,即使在只有一个处理器的系统中也有意义;交替推进多个任务,并不等于它们在不同核心上同时执行。

参考:[1] [2]

时钟、中断与调度决定

计时器中断是让内核重新取得控制的一种机制。硬件保存必要状态并进入处理程序后,内核可以检查是否需要更换运行任务。若决定切换,就保存当前任务的相关寄存器和栈等上下文,恢复另一任务的状态。因此,中断入口、调度决策和上下文切换是相连却不同的步骤;处理完一次中断后也可能仍返回原任务。

轮转策略在时间片用完时给其他就绪任务机会。另一种情形是等待输入输出的较高优先级线程被唤醒。在Linux的固定优先级实时策略中,较高优先级线程就绪可抢占较低优先级线程。SCHED_FIFO本身不实行同级时间片轮转,却仍可被更高优先级线程抢占;SCHED_RR则增加了同级时间片规则。

参考:[1] [3]

响应时间与切换代价

设一个单处理器上的两个同级任务都需要持续计算,若采用轮转,后到者不必等待先到者全部完成才开始工作。这里改善的是获得首次运行机会的等待时间,并不必然缩短每个任务从到达到完成的周转时间。不同评价指标可以导向不同策略,“更快响应”并不等于“更快完成全部工作”。

时间片缩短通常使轮流得到执行机会更及时,但过短会增加切换频率。成本不只在保存和恢复寄存器,还涉及缓存、地址转换等硬件状态的利用变化。时间片过长则使系统更接近长时间独占,交互体验可能下降。合适尺度取决于工作负载与机器,而不是一个通用毫秒数。

参考:[2]

抢占仍有边界

内核在操作某些状态时,不能任由任务在任意位置被换走。例如,代码先读取当前处理器编号,再访问该处理器专属数据;若中途被抢占并迁移,前后可能落在不同处理器。Linux提供显式禁止与恢复抢占的接口,以围住需要这种保护的短临界区。

这也意味着“高优先级就绪”不等于不受任何条件限制地立即开始执行。不可抢占区会影响实际响应延迟,而把临界区无限延长又会损害及时性。禁止本地抢占也不是跨处理器互斥的替代品,共享数据仍须依访问关系采用适当锁或其他同步机制。抢占能力与状态保护必须共同设计。

参考:[4] [1]