cfs调度的抢占

本文解析了Linux内核中CFS调度器的特性,探讨了不同policy之间的抢占规则,如sched_normalpolicy和sched_idlepolicy,以及唤醒任务的处理方式。重点介绍了check_preempt_wakeup和place_entity等关键函数在抢占决策中的作用。

结论分析

  1. 不能的policy之间是可以抢占的,比如sched_normal policy可以抢占sched_idle policy 的任务。 sched_batch 不抢占
  2. 唤醒时的唤醒任务和被幻想任务,如果两个特性 next_buddy 以及 last_buddy被打开的话,是可以支持抢占的
  3. 如果wakeup任务的vruntime时间小于curr的vruntime时间,差值大于sysctl_sched_wakeup_granularity, 则设置next_buddy (set_next_buddy)

#涉及的函数
check_preempt_wakeup 可能会设置NEXT_BUDDY 和 LAST_BUDDY, cfs_rq里面有next和last 指针,支持抢占
place_entity (会对睡眠进程以及新创建的进程分配vruntime时间片)
pick_next_entity

主要函数分析

### CFS调度器的工作原理 CFS(Completely Fair Scheduler)是Linux内核中用于管理普通进程的调度器,其设计目标是实现对所有进程的公平调度CFS的核心思想是通过虚拟时间(vruntime)来衡量进程的执行时间,从而确保每个进程都能获得大致相等的CPU时间[^1]。 #### 基本原理 CFS的基本原理是将进程的执行时间转换为虚拟时间,以消除进程优先级的影响。虚拟时间的计算基于进程的实际运行时间和其nice值,其中nice值较低的进程会得到更多的CPU时间。具体来说,CFS维护一个红黑树(Red-Black Tree),用于存储所有就绪态的进程调度实体(`sched_entity`)。红黑树按照虚拟时间排序,最小的虚拟时间位于树的最左边。CFS总是选择虚拟时间最小的进程来执行,这样可以保证系统的公平性[^3]。 #### 实现机制 CFS的实现主要依赖于以下几个关键数据结构和机制: 1. **调度实体(`sched_entity`)**:每个进程在CFS中被表示为一个调度实体,它包含了进程的虚拟时间(`vruntime`)、权重(`load`)以及其他相关信息。调度实体通过红黑树节点(`rb_node`)插入到红黑树中。 2. **红黑树(`cfs_rq`)**:每个CPU都有一个对应的CFS就绪队列(`cfs_rq`),该队列维护了一个红黑树,按虚拟时间排序。红黑树的最左节点(`rb_leftmost`)指向当前虚拟时间最小的调度实体,这使得CFS能够快速找到下一个要执行的进程。 3. **虚拟时间(`vruntime`)**:虚拟时间是CFS的核心概念之一,它是根据进程的实际运行时间和其权重计算得出的。公式如下: ```math vruntime = actual_runtime \times \frac{NICE_0_LOAD}{weight} ``` 其中,`actual_runtime`是进程实际运行的时间,`NICE_0_LOAD`是一个基准权重,`weight`是进程的权重。权重越高,进程的优先级越低,因此需要更少的虚拟时间来反映其公平性。 4. **周期性调度**:CFS通过周期性调度器(periodic scheduler)定期检查当前运行的进程是否应该被抢占。如果当前进程的虚拟时间超过了其他进程的虚拟时间,则会发生抢占,确保系统始终选择虚拟时间最小的进程执行。 5. **唤醒抢占**:当一个进程从睡眠状态醒来时,CFS会检查它是否比当前正在运行的进程具有更低的虚拟时间。如果是,则触发抢占,让新唤醒的进程立即获得CPU资源。 6. **最小粒度控制**:为了防止过于频繁的上下文切换,CFS设定了一个最小调度粒度(`sched_min_granularity_ns`),默认值为1500000纳秒(1.5毫秒)。这意味着即使某个进程的虚拟时间低于当前运行进程,只要当前进程的运行时间不足这个最小粒度,就不会被抢占[^4]。 7. **组调度**:CFS支持组调度(Group Scheduling),允许将多个进程分组,并为每个组分配一定的CPU带宽。这种方式可以更好地管理和限制不同用户或服务之间的资源使用[^2]。 #### 优化方法 为了进一步提升CFS的性能和公平性,Linux内核引入了一些优化措施: 1. **负载均衡**:CFS通过负载均衡算法确保各个CPU上的任务分布尽可能均匀,避免某些CPU过载而其他CPU空闲的情况。负载均衡通常在系统空闲或周期性调度时进行。 2. **缓存友好性**:CFS的设计考虑了现代处理器的缓存特性,尽量减少跨CPU的任务迁移,以降低缓存失效带来的性能损失。 3. **动态调整权重**:CFS可以根据系统的负载情况动态调整进程的权重,确保高优先级任务能够在必要时获得更多CPU时间。 4. **多核支持**:CFS针对多核处理器进行了优化,确保在多核环境下依然能够保持良好的公平性和响应速度。 5. **实时调度类集成**:虽然CFS主要用于普通进程,但它与实时调度类(如SCHED_FIFO和SCHED_RR)紧密集成,确保实时任务能够在需要时立即抢占普通任务。 ### 相关问题 1. 如何查看和修改CFS调度器的参数? 2. CFS调度器是如何处理进程优先级的? 3. 在多核系统中,CFS如何实现负载均衡? 4. CFS调度器中的红黑树是如何维护的? 5. CFS调度器与O(1)调度器的主要区别是什么?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值