尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Linux 内核 5.x 实时调度类 rt_sched_class 源码解析:FIFO/RR 队列与时间片实现
Linux 内核实时调度类 rt_sched_class 深度解析从数据结构到时间片管理在操作系统内核的世界里调度器如同交通指挥中心决定着每个进程何时获得CPU资源。而实时调度类rt_sched_class则是这个指挥中心里处理紧急任务的特殊通道专门为那些对延迟极度敏感的任务提供服务。本文将带您深入Linux内核5.x版本的实时调度实现揭开SCHED_FIFO和SCHED_RR两种实时调度策略背后的精妙设计。1. 实时调度的核心数据结构要理解Linux实时调度的运作机制首先需要掌握其基础数据结构。内核通过两个关键结构体来管理实时任务struct sched_rt_entity { struct list_head run_list; unsigned long timeout; unsigned int time_slice; struct sched_rt_entity *back; /* 其他字段省略... */ }; struct rt_rq { struct rt_prio_array active; unsigned int rt_nr_running; u64 rt_time; u64 rt_runtime; /* 其他字段省略... */ };这两个结构体构成了实时调度的骨架sched_rt_entity嵌入在每个实时任务中的调度实体包含run_list将该实体链接到运行队列的链表节点time_sliceRR策略下的剩余时间片FIFO策略下为0timeout用于带宽控制的超时计时rt_rq实时运行队列管理所有可运行的实时任务active按优先级组织的任务数组稍后详解rt_nr_running当前队列中可运行任务数rt_time和rt_runtime用于实时带宽控制实时调度队列的核心是rt_prio_array结构它使用位图和链表高效管理不同优先级的任务struct rt_prio_array { DECLARE_BITMAP(bitmap, MAX_RT_PRIO1); /* 包含1个哨兵位 */ struct list_head queue[MAX_RT_PRIO]; };这个设计有三大精妙之处位图快速查找通过find_first_bit()可以快速找到最高优先级的非空队列优先级隔离每个优先级1-99有独立的链表避免优先级反转O(1)调度复杂度无论系统中有多少任务选择下一个任务都是常数时间提示Linux实时优先级范围是1-99数值越大优先级越高。这与nice值-20到19的约定相反使用时需特别注意。2. 任务入队与出队机制实时调度的核心操作体现在任务进出队列的过程中。内核通过一组函数指针将这些操作抽象为调度类接口2.1 enqueue_task_rt任务入队当实时任务变为可运行状态时enqueue_task_rt()会被调用static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags) { struct sched_rt_entity *rt_se p-rt; struct rt_rq *rt_rq rt_rq_of_se(rt_se); /* 如果任务先前已在队列中只需更新其位置 */ if (flags ENQUEUE_RESTORE) { if (rt_se-on_rq) goto out; } /* 对于RR任务如果时间片耗尽则重置 */ if (p-policy SCHED_RR !rt_se-time_slice) rt_se-time_slice sched_rr_timeslice; /* 将任务添加到对应优先级的链表头部 */ list_add(rt_se-run_list, rt_rq-active.queue rt_se_prio(rt_se)); __set_bit(rt_se_prio(rt_se), rt_rq-active.bitmap); /* 更新统计信息 */ rt_rq-rt_nr_running; inc_rt_tasks(p, rq); out: /* 触发抢占检查 */ if (p-prio rq-curr-prio) resched_curr(rq); }关键点解析FIFO与RR的区别处理只有RR策略的任务会重置时间片优先级队列管理任务被添加到对应优先级的链表头部FIFO特性位图更新设置对应优先级位确保快速查找抢占检查如果新任务优先级更高立即触发重新调度2.2 dequeue_task_rt任务出队当任务因阻塞、退出等原因需要离开运行队列时static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags) { struct sched_rt_entity *rt_se p-rt; struct rt_rq *rt_rq rt_rq_of_se(rt_se); /* 从优先级链表中移除 */ list_del_init(rt_se-run_list); /* 如果这是该优先级最后一个任务清除位图 */ if (list_empty(rt_rq-active.queue rt_se_prio(rt_se))) __clear_bit(rt_se_prio(rt_se), rt_rq-active.bitmap); /* 更新统计信息 */ rt_rq-rt_nr_running--; dec_rt_tasks(p, rq); /* 处理组调度相关逻辑简化 */ dequeue_rt_entity(rt_se, flags); }出队操作与入队对称但有几个值得注意的细节链表状态维护使用list_del_init()确保节点可以被安全重用位图同步更新当某优先级队列为空时及时清除位图统计信息准确确保运行任务计数实时准确3. 时间片管理与RR调度SCHED_RR策略的核心在于时间片管理这通过task_tick_rt()函数实现static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued) { struct sched_rt_entity *rt_se p-rt; update_curr_rt(rq); /* FIFO任务不处理时间片 */ if (p-policy ! SCHED_RR) return; /* 时间片递减 */ if (--p-rt.time_slice) return; /* 时间片耗尽时的处理 */ p-rt.time_slice sched_rr_timeslice; /* 如果队列中还有其他任务将当前任务移到队尾 */ for_each_sched_rt_entity(rt_se) { if (rt_se-run_list.prev ! rt_se-run_list.next) { requeue_task_rt(rq, p, 0); resched_curr(rq); return; } } }时间片管理的几个关键机制默认时间片设置通过sched_rr_timeslice变量控制默认为100ms时间片递减每次时钟中断减少1个tick通常1-10ms队列轮转当时间片耗尽且同优先级有其他任务时当前任务被移到队尾时间片长度可通过/proc/sys/kernel/sched_rr_timeslice_ms动态调整内核处理流程如下int sched_rr_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; static DEFINE_MUTEX(mutex); mutex_lock(mutex); ret proc_dointvec(table, write, buffer, lenp, ppos); /* 写入的值转换为jiffies */ if (!ret write) { sched_rr_timeslice sched_rr_timeslice 0 ? RR_TIMESLICE : msecs_to_jiffies(sched_rr_timeslice); } mutex_unlock(mutex); return ret; }注意写入sched_rr_timeslice_ms的值以毫秒为单位但读取时显示的是转换后的jiffies值。设置为0会恢复默认值。4. 实时带宽控制机制为防止实时任务独占CPU导致系统无响应Linux实现了实时带宽控制控制参数默认值说明sched_rt_period_us1,000,000带宽计算周期1秒sched_rt_runtime_us950,000每个周期内实时任务最大运行时间0.95秒带宽控制的实现涉及多个组件定时器检查通过hrtimer定期执行sched_rt_period_timer()时间记账在update_curr_rt()中累计运行时间超额处理当运行时间超过配额时通过sched_rt_runtime_exceeded()触发限流关键代码逻辑static enum hrtimer_restart sched_rt_period_timer(struct hrtimer *timer) { struct rt_bandwidth *rt_b container_of(timer, struct rt_bandwidth, rt_period_timer); int idle 0; int overrun; raw_spin_lock(rt_b-rt_runtime_lock); for (;;) { overrun hrtimer_forward_now(timer, rt_b-rt_period); if (!overrun) break; raw_spin_unlock(rt_b-rt_runtime_lock); idle do_sched_rt_period_timer(rt_b, overrun); raw_spin_lock(rt_b-rt_runtime_lock); } if (idle) rt_b-rt_period_active 0; raw_spin_unlock(rt_b-rt_runtime_lock); return idle ? HRTIMER_NORESTART : HRTIMER_RESTART; }带宽控制的工作流程每个CPU维护自己的rt_time累计值定时器周期性地从rt_time中扣除分配的时间配额当rt_time超过sched_rt_runtime_us时设置rt_throttled标志被限流的任务会被移出运行队列直到下一个周期这种设计既保证了实时任务可以获得大部分CPU资源又为普通任务保留了必要的响应能力。
RELATED

相关推荐

OpenTelemetry-proto性能优化指南:提升OTLP传输效率的7个技巧

OpenTelemetry-proto性能优化指南:提升OTLP传输效率的7个技巧

OpenTelemetry-proto性能优化指南:提升OTLP传输效率的7个技巧 【免费下载链接】opentelemetry-proto OpenTelemetry protocol (OTLP) specification and Protobuf definitions 项目地址: https://gitcode.com/gh_mirrors/op/opentelemetry-proto OpenTelemet…

📅 2026/11/11 4:12:15
3款主流Modbus CRC在线计算工具实测:高低字节顺序与结果一致性分析

3款主流Modbus CRC在线计算工具实测:高低字节顺序与结果一致性分析

3款主流Modbus CRC在线计算工具实测:高低字节顺序与结果一致性分析 在工业自动化与物联网系统调试中,Modbus RTU协议因其简单可靠的特点被广泛应用。作为协议核心的CRC校验机制,其计算准确性直接关系到通信质量。本文将针对工程师日常调试中的…

📅 2026/9/15 15:27:12
Unity Shader开发实战:从理论到可运行资产的完整实现指南

Unity Shader开发实战:从理论到可运行资产的完整实现指南

1. 项目概述:从“12.4.2”说起看到“《Unity Shader》12.4.2 实现”这个标题,我猜很多Unity开发者,尤其是对渲染技术感兴趣的朋友,会立刻会心一笑。这大概率不是指某个具体的、公开的Shader资源包,而更像是一个内部约定…

📅 2026/9/15 15:37:14
MORE NEWS

更多资讯

📰

绍兴上虞电工证怎么选?郑州报考避坑指南全在这了

绍兴上虞电工证怎么选?郑州报考避坑指南全在这了 之前考的证在外省能不能转过来?这是很多在绍兴上虞的朋友问我的第一句话。我懂,你可能是在郑州干过电工,后来回老家想继续干这行,但证书在外地,不知道怎么操作。别急,今天就用我的亲身经历和真实案例,…

📰

龙江哪里考电工证多久拿证别被中介坑

龙江哪里考电工证多久拿证别被中介坑 你是不是也担心去哪报名电工证?怕被中介坑?别急,这篇文章就告诉你【龙江哪里考电工证】,多久能拿证,还有避坑指南,全是干货! 电工证到底值不值?先搞清楚它的用处…

📰

低压电工证c11复合照明线路安装保姆级教程:别被中介坑了,这样报名才靠谱

低压电工证c11复合照明线路安装保姆级教程:别被中介坑了,这样报名才靠谱 你是不是也遇到过这样的情况:想考低压电工证c11复合照明线路安装,结果在网上一搜,全是“包过”“包办”的广告,让人真假难辨,生怕一不小心就被中介坑了?别担心,这篇保姆…

📰

特种工思索证年审最新政策出炉,官方报名入口你知道吗?

特种工思索证年审最新政策出炉,官方报名入口你知道吗? 怕考不过白交培训费,特种工思索证年审流程你搞懂了吗?今年政策有变化,错过再等一年。很多人在报名前总担心自己会不会因为操作不熟练、考试内容不熟悉而挂科,结果培训费打了水漂。其实只要你选对官…

📰

电工证体检抽血查什么 官方回应抽血项目全公开

电工证体检抽血查什么 官方回应抽血项目全公开 证书过期了不知道怎么复审延期?别慌,这是很多电工朋友遇到的常见问题。特别是那些初次报考电工证的新手,对体检流程、项目都不太清楚,尤其是 电工证体检抽血查什么…

📰

外地电工作业证怎么审?2026河南最新政策怎么走?别再被中介坑了

外地电工作业证怎么审?2026河南最新政策怎么走?别再被中介坑了 你是不是正愁不知道外地电工作业证怎么审,怕被中介坑得连报名费都白交?特别是2026年河南最新政策一出,很多在外务工的朋友都懵了。别急,咱们一步步来,看完这篇,你就能搞懂流程,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬