Linux系统下sched_yield与nice值的交互逻辑及调度行为问询
Linux系统
sched_yield()与nice值交互问题解答 核心结论
sched_yield() 是否会允许更低优先级的进程获得运行机会,取决于进程所属的调度类,不能一概而论。
1. 实时调度类(SCHED_FIFO、SCHED_RR 场景)
该场景完全符合 sched_yield() 手册页的描述:
- 调用
sched_yield()后,内核仅会将当前线程放到同优先级调度队列的队尾,只会选择同优先级或更高优先级的其他就绪线程运行 - 若当前CPU运行队列中没有优先级≥当前线程的其他就绪线程,当前线程会立刻继续运行,绝对不会给更低优先级的实时进程、以及任何SCHED_OTHER类普通进程让出CPU
2. 普通调度类(SCHED_OTHER,即CFS调度器管理的进程场景)
该场景下规则和实时调度完全不同,确实存在让更低nice值(即更低优先级)的进程获得运行机会的可能,核心原因如下:
CFS调度器没有严格的优先级队列概念,核心逻辑是按权重分配CPU时间,所有就绪进程按
vruntime(虚拟运行时间)排序,永远选择vruntime最小的进程运行。
调用sched_yield()时,CFS的处理逻辑是直接把当前进程的vruntime调整为当前CPU运行队列中的最大vruntime值,强制它排到调度队列末尾。这个操作不会比较进程的nice值(优先级),只要队列中其他所有就绪进程的vruntime都小于调整后的当前进程vruntime,无论它们的nice值比当前进程高还是低,都会被优先调度运行。
实际示例
假设存在两个SCHED_OTHER进程:
- 进程A:nice=-10(高优先级,权重大),已经运行较长时间,vruntime累积到1000
- 进程B:nice=+10(低优先级,权重小),刚进入就绪队列,vruntime仅为100
此时进程A调用sched_yield(),CFS会将进程A的vruntime直接拉高到当前队列最大值(≥1000),接下来调度器自然会优先选择vruntime仅100的低优先级进程B运行,哪怕它的nice值更低、优先级更差。
你提到的nice值每差1单位调度倾斜1.25倍的规则,是用来计算vruntime的增长速度的:nice越高(优先级越高)的进程vruntime增长越慢,本质是保证长期运行下高优先级进程能拿到更多CPU时间,但这和sched_yield()的即时调度逻辑并不冲突。
注:以上为Linux 2.6.23引入CFS调度器后的实现逻辑,更早的O(1)调度器下SCHED_OTHER类的sched_yield逻辑更接近实时调度,不会主动让给更低优先级进程。
内容的提问来源于stack exchange,提问作者SRobertJames
相关产品推荐
相关产品推荐

