FreeRTOS中创建任务的顺序是否会影响任务运行的顺序?【面试重点】

结论

任务的运行顺序 和 创建顺序 没有任何关系! FreeRTOS 是抢占式调度器,任务执行顺序只由 2 个规则决定:

  1. 优先级高的任务 → 永远先运行(核心规则)
  2. 同优先级任务新创建的任务会立即抢占当前任务 ,直接导致后创建、先运行

原理(FreeRTOS 调度核心机制)

1. 抢占式调度器(最重要)

FreeRTOS 默认开启 抢占式调度

  • 只要有更高优先级 的任务进入就绪态,CPU 会立刻停止当前任务,去运行高优先级任务
  • 优先级:数值越大,优先级越高(CMSIS-V2 / STM32CubeMX 配置)

2. 同优先级任务的规则

创建的任务优先级完全相同 (都是 osPriorityNormal):

  1. 同优先级任务默认使用 时间片轮转调度
  2. 新创建的任务 会被插入到就绪链表的头部
  3. 调度器会立即切换 到这个新任务运行→ 表现为:谁后创建,谁先抢 CPU 运行

3. 补充:调度器启动前创建任务

如果在 vTaskStartScheduler() 之前创建所有任务:

  • 所有任务排队进入就绪链表
  • 调度器启动后,运行最高优先级任务
  • 同优先级:运行链表第一个任务(先创建的先运行)

运行机制

cpp 复制代码
// 都是 osPriorityNormal 同优先级
xTaskCreate(Input_Task, ...);  // 先创建
xTaskCreate(platform_task, ...); // 后创建

执行流程:

  1. CPU 正在运行 game1_task
  2. 调用 xTaskCreate 创建 platform_task
  3. 新任务优先级 = 当前任务优先级
  4. FreeRTOS 直接抢占切换 :暂停 game1_task,先运行 platform_task
  5. 所以你看到:后创建的任务先运行

可复制验证代码(直观看到效果)

cpp 复制代码
// 三个同优先级任务
void Task1(void *p)
{
    while(1)
    {
        LCD_PrintString(0,0,"Task1 Run");
        vTaskDelay(500);
    }
}

void Task2(void *p)
{
    while(1)
    {
        LCD_PrintString(0,2,"Task2 Run"); // 后创建,会先打印!
        vTaskDelay(500);
    }
}

void game1_task(void *params)
{
    // 先创建 Task1
    xTaskCreate(Task1, "Task1", 128, NULL, osPriorityNormal, NULL);
    // 后创建 Task2
    xTaskCreate(Task2, "Task2", 128, NULL, osPriorityNormal, NULL);

    while(1)
    {
        vTaskDelay(100);
    }
}

✅ 现象:LCD 先显示 Task2 Run,验证后创建先运行


避坑提醒(STM32F103 + FreeRTOS 专属)

  1. 绝对不要依赖「任务创建顺序」控制执行流程 同优先级任务的执行顺序是不确定的,换芯片 / 升级库可能失效

  2. 需要优先运行的任务 → 提高优先级例:平台控制任务需要优先运行

    复制代码
    // 高优先级
    xTaskCreate(platform_task, ..., osPriorityAboveNormal, NULL);
    // 普通优先级
    xTaskCreate(Input_Task, ..., osPriorityNormal, NULL);
  3. 业务同步不要靠执行顺序队列、任务通知、互斥锁、信号量 做任务同步(你项目中已用队列,正确)

  4. 抢占式调度默认开启这是 FreeRTOS 标准配置,不要关闭,否则系统实时性崩溃

相关推荐
未来之窗软件服务3 小时前
计算机二级[英文]-C 字符串移动—东方仙盟
c语言·开发语言·仙盟创梦ide·东方仙盟
是隼人8 小时前
buuctf-pwn bypwn(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
T1mzhou9 小时前
ARM64 Linux 6.10内核启动流程6-psci.c和ATF/U-Boot 的电源接口
linux·服务器·c语言
是隼人9 小时前
buuctf-pwn PWN2(整数溢出)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
LuminousCPP10 小时前
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
c语言·数据结构·笔记·算法·排序算法
竞赛考级题库10 小时前
202606 青少年等级考试C/C++真题一级 建议答题时长:60min
java·c语言·c++
迷茫、Peanut10 小时前
C语言混合链接
c语言
wdfk_prog11 小时前
RT-Thread Kconfig 配置明明是 y,为什么 rtconfig.h 就是不生成?一次 `_PATH` 后缀踩坑复盘
c语言
是隼人11 小时前
buuctf-pwn jarvisoj_level5(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
Suxing912 小时前
C语言基础分享:C语言文件操作:从“写日记”到“拍电影”的存盘指南
c语言·开发语言