You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FreeRTOS同优先级任务访问共享全局变量是否会互相打断?

FreeRTOS同优先级任务并发问题解答

核心结论

同优先级的FreeRTOS任务之间存在互相打断的可能,你给出的代码存在明确的共享变量并发访问风险,这类问题并非只有优先级不同的任务抢占、或者中断打断场景才会出现。

具体原因

  • FreeRTOS默认开启*时间片轮转调度(Round Robin)*机制:所有同优先级的就绪态任务,会以系统时钟Tick为单位轮流分配CPU时间片。每个任务用完一个时间片(默认配置为1个系统Tick)后,调度器会直接切走当前任务,执行同优先级的其他就绪任务,该过程不需要当前任务主动调用任何阻塞类API(如vTaskDelay、信号量/队列等待函数等)就会触发。
  • 代码中的global_var++不是原子操作,底层汇编会拆分为3步:读取变量值到CPU寄存器、寄存器值+1、将新值写回变量对应的内存地址。如果操作执行到中途时间片耗尽,任务被切换走,就会出现共享变量值异常的问题。

异常场景示例

假设global_var初始值为0,task1刚把变量值0读到寄存器中,还没执行+1和写回操作,时间片耗尽被切走;task2获得CPU后完整执行了3次自增操作,此时global_var已经被更新为3;等调度器切回task1继续执行时,会基于之前读取的旧值0完成+1操作,写回后global_var被改为1,task2的3次自增结果直接被覆盖丢失。

补充说明

如果手动在FreeRTOSConfig.h中将configUSE_TIME_SLICING配置为0关闭时间片轮转,那么同优先级任务不会自动切换,只有当前运行任务主动进入阻塞、挂起状态时,才会调度同优先级的其他任务。但你当前代码中的两个任务都是没有阻塞逻辑的死循环,关闭时间片轮转的情况下会永远运行先创建的task1,task2永远得不到CPU执行权,这属于非默认的特殊配置。

只要存在多个并发执行流(不同优先级任务、同优先级任务、中断服务函数)同时访问可写共享资源,都需要做临界区保护:你这个场景可以用mutex互斥锁包裹自增操作,也可以用taskENTER_CRITICAL()/taskEXIT_CRITICAL()临界区宏包裹操作。


内容的提问来源于stack exchange,提问作者TheBestPlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:24:05