当前位置: 首页 > news >正文

【计算机基础】-27-RT-Thread-idle线程如何计算自己的执行时间?

在 RT-Thread(以及其他主流 RTOS)中,idle 线程并不“自己计算”自己的执行时间,而是由操作系统内核(调度器)在每次线程切换时统一统计所有线程(包括 idle)的运行时间idle 线程本身只是一个“被统计的对象”,而非“统计的执行者”。


✅ 核心结论:

idle 线程的执行时间是由调度器在线程切换时精确累加的,而不是 idle 线程自己通过start_time/end_time计算的。


一、为什么 idle 线程不能自己计算?

正如你之前敏锐指出的:

如果 idle 线程用tick_start = get_time(); ...; tick_end = get_time();
中途被中断或高优先级线程抢占,会导致tick_end - tick_start包含非 idle 时间 →统计错误

因此,任何成熟的 RTOS 都不会让 idle 线程自己测量时间


二、RT-Thread 的真实实现机制

✅ 方法:调度器在上下文切换时打时间戳

工作流程:
  1. 系统维护一个高精度时间源(如 Cortex-M 的 DWT Cycle Counter);
  2. 每次发生线程切换(通过 PendSV 异常)时:
    • 调度器记录当前时间T_now
    • (T_now - T_last)累加到即将被换出的线程runtime字段;
    • 更新T_last = T_now
    • 切换到新线程。
  3. idle 线程只是众多线程之一,它的runtime也被同样方式累加。
示意图:
时间轴: |----[线程A]----|---[idle]---|---[线程B]---|---[idle]---| ↑ ↑ ↑ ↑ T0 (初始) T1 T2 T3 - 在 T1:线程A被换出 → A.runtime += (T1 - T0) - 在 T2:idle被换出 → idle.runtime += (T2 - T1) - 在 T3:线程B被换出 → B.runtime += (T3 - T2)

idle 的运行时间 = 所有它被换出时累加的时间段之和


三、关键代码解析(RT-Thread 源码)

1.线程控制块增加 runtime 字段

// rtdef.h struct rt_thread { ... #ifdef RT_USING_THREAD_RUNTIME_STATISTICS rt_uint64_t runtime; // 累计运行时间(cycles) #endif };

2.上下文切换时更新 runtime(Cortex-M 示例)

libcpu/arm/cortex-m/cpuport.c中:

#ifdef RT_USING_THREAD_RUNTIME_STATISTICS static rt_uint32_t last_cyc = 0; void rt_update_runtime(rt_ubase_t *sp) { rt_uint32_t cyc_now = DWT_CYCCNT; // 读取当前 cycle 计数 rt_thread_t thread = rt_current_thread; // 即将被换出的线程 if (last_cyc == 0) { last_cyc = cyc_now; return; } if (thread) { /* 将本次运行时间累加到该线程 */ thread->runtime += (cyc_now - last_cyc); } last_cyc = cyc_now; } #endif

🔔 此函数在PendSV 异常处理(线程切换)时被调用。

3.idle 线程本身不参与计算

idle 线程入口函数(rt_thread_idle_entry)非常简单:

void rt_thread_idle_entry(void *parameter) { while (1) { if (rt_thread_idle_hook != RT_NULL) rt_thread_idle_hook(); // 可挂载用户 hook(如低功耗) /* 注意:这里没有时间测量代码! */ } }

四、CPU 使用率如何得出?

当需要计算 CPU 使用率时(如调用rt_cpu_get_usage()):

// 伪代码 rt_thread_t idle = rt_thread_find("tidle0"); rt_uint64_t total_time = DWT_CYCCNT; // 总 elapsed cycles rt_uint64_t idle_time = idle->runtime; // idle 累计运行时间 cpu_usage = (total_time - idle_time) * 100 / total_time;

✅ 所有数据都来自调度器维护的runtime字段,与 idle 线程自身逻辑无关


五、优势总结

优势说明
精确只统计线程真正占用 CPU 的时间
抗抢占中断、高优先级线程切换不影响统计
统一所有线程(包括 idle)使用同一套机制
低开销每次切换仅一次减法+加法

六、常见误解澄清

误解事实
“idle 线程自己计时”❌ 完全由调度器统计
“用 tick 差值计算”❌ 使用高精度 cycle counter(DWT)
“idle 运行越久,统计越不准”❌ 无论运行多久,每次切换都精确累加

✅ 总结

idle 线程的执行时间不是它自己算的,而是调度器在每次把它换出去的时候,说:“你刚才跑了 X 个 cycle,记到账上。”

这种机制确保了统计的精确性、可靠性和高效性,是 RTOS 设计的经典范式。

这种设计也解释了为什么你看到的 RT-Thread 源码中,idle 线程函数里没有任何时间测量代码——因为它根本不需要!

http://www.jsqmd.com/news/374471/

相关文章:

  • IC697BEM761总线控制器卡
  • 企业级指标中台 API/JDBC 架构选型四步法
  • Redis6为何引入多线程?
  • 双相钢法兰供应商分析,助您做出明智选择,不锈钢法兰/非标法兰/变压器法兰/不锈钢管板/船用法兰,双相钢法兰公司找哪家 - 品牌推荐师
  • 5 款即时通讯软件对比 - 企业数字化观察家
  • 2026全自动商用咖啡机靠谱品牌与厂家推荐,商用咖啡设备新潮流 - 品牌2025
  • 分期乐的携程卡套装回收最简单方法 - 团团收购物卡回收
  • 【计算机基础】-26-RT-Thread-实际系统中,计算CPU使用率的原理与算法,代码示例
  • 2026智能咖啡机哪家好?怎么选?质量优服务佳的智能咖啡机厂家 - 品牌2025
  • 2026年,银川学校装修找哪家?优先选津都华丽 本地20年工装经验 - 宁夏壹山网络
  • 告别低效繁琐!当红之选的降AIGC工具 —— 千笔·降AI率助手
  • 单北斗GNSS在变形监测中的应用与优势分析
  • 2026年2月抗皱紧致护肤品品牌推荐,配方、专利、肤感三维数据透视 - 品牌鉴赏师
  • 2026高奢酒店智能咖啡机推荐 高端商务接待高品质咖啡需求 - 品牌2025
  • 2026必备!AI论文工具 千笔 VS speedai,自考写作新选择!
  • 题4
  • 2026年咖啡连锁商用咖啡机推荐 全自动高效稳定机型合集 - 品牌2025
  • 深度相机原理(TOF、双目、结构光)
  • 交稿前一晚!研究生必备的降AI率神器 —— 千笔·专业降AI率智能体
  • 2026更新版!AI论文写作软件 千笔AI VS PaperRed,研究生写论文神器!
  • 真心不骗你!专科生专用降AI率工具,千笔 VS 知文AI
  • Jenkins 启动的命令
  • 10个新颖的springboot毕业设计题目(非烂大街版)
  • 探讨日本经营管理签证申请公司,广州上海哪家口碑好 - 工业设备
  • 永辉超市卡回收成功后,资金多久到账? - 京顺回收
  • 软考高项计算:她终于搞懂了当年中项计算题错在哪
  • 如何快速回收分期乐礼品卡?推荐高效平台,让闲置卡变现轻松! - 团团收购物卡回收
  • 2026年北京可靠的CE认证公司排名,郜盟认证助力企业轻松拿证 - 工业推荐榜
  • 济宁GEO优化服务公司选型攻略破解本地流量即时性困局 - 博客万
  • 2026年碳化铪供应商排名揭晓,这些品牌值得关注 - mypinpai