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

【FreeRTOS】任务间通讯3:互斥量- Mutex

       想象一下这样的场景:几个任务像饿狼一样盯着同一块"肥肉"(共享资源),如果不加以控制,结果会怎样?数据被改得面目全非,系统行为变得莫名其妙——这就是典型的多任务"修罗场"!

    在FreeRTOS的多任务世界里,共享资源就像公司里唯一的打印机:

  • 当财务部正在打印工资单时...

  • 市场部突然插队打印宣传册...

  • 结果?工资单上可能印满了产品广告

    互斥量(Mutex)!它就像资源的"独享VIP卡

一、互斥量简介

互斥量(Mutex, Mutual Exclusion)是FreeRTOS中用于任务间同步的一种机制,主要用于保护共享资源,防止多个任务同时访问同一资源导致的数据不一致问题。互斥量是一种特殊的二进制信号量,具有优先级继承机制,可以有效解决优先级反转问题。

二、互斥量的作用

  1. 资源保护:确保同一时间只有一个任务可以访问共享资源

  2. 解决竞争条件:防止多个任务同时修改共享数据导致的不一致

  3. 优先级继承:当高优先级任务因等待低优先级任务持有的互斥量而阻塞时,低优先级任务会临时继承高优先级任务的优先级

  4. 线程安全:实现关键代码段的互斥访问

三、互斥量API接口

1. 创建互斥量

SemaphoreHandle_t xSemaphoreCreateMutex( void );

参数:无
返回值:成功返回互斥量句柄,失败返回NULL

2. 获取互斥量

BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );

参数

  • xSemaphore:互斥量句柄

  • xTicksToWait:等待时间(单位:时钟节拍),可使用portMAX_DELAY表示无限等待

返回值

  • pdPASS:成功获取互斥量

  • pdFAIL:获取失败(超时)

3. 释放互斥量

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

参数

  • xSemaphore:互斥量句柄

返回值

  • pdPASS:成功释放互斥量

  • pdFAIL:释放失败(通常表示当前任务不持有该互斥量)

4. 删除互斥量

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

参数

  • xSemaphore:要删除的互斥量句柄

四、应用Demo实例

以下是一个使用互斥量保护共享资源的示例:

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"// 共享资源
static int sharedCounter = 0;// 互斥量句柄
SemaphoreHandle_t xMutex;// 任务1:增加计数器
void vTask1(void *pvParameters) {while(1) {// 获取互斥量if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdPASS) {// 临界区开始sharedCounter++;printf("Task1: Counter = %d\n", sharedCounter);// 临界区结束// 释放互斥量xSemaphoreGive(xMutex);}vTaskDelay(pdMS_TO_TICKS(100));}
}// 任务2:减少计数器
void vTask2(void *pvParameters) {while(1) {// 获取互斥量if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdPASS) {// 临界区开始sharedCounter--;printf("Task2: Counter = %d\n", sharedCounter);// 临界区结束// 释放互斥量xSemaphoreGive(xMutex);}vTaskDelay(pdMS_TO_TICKS(150));}
}int main(void) {// 创建互斥量xMutex = xSemaphoreCreateMutex();if(xMutex == NULL) {printf("Mutex creation failed!\n");return -1;}// 创建任务xTaskCreate(vTask1, "Task1", configMINIMAL_STACK_SIZE, NULL, 2, NULL);xTaskCreate(vTask2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, NULL);// 启动调度器vTaskStartScheduler();// 正常情况下不会执行到这里while(1);return 0;
}

五、使用注意事项

  1. 获取与释放配对:每次成功获取互斥量后必须释放,否则会导致其他任务永久阻塞

  2. 避免死锁

         *  不要嵌套获取同一个互斥量

         *  获取多个互斥量时保持一致的顺序

     3.临界区最小化:保持临界区代码尽可能短,避免长时间持有互斥量

     4.优先级继承:理解互斥量的优先级继承机制,合理设置任务优先级

     5.不要用于ISR:互斥量不能在中断服务例程中使用(使用信号量替代)

     6.资源释放:动态创建的互斥量在使用完毕后应删除以释放内存

     7.递归互斥量:对于需要递归获取的情况,使用xSemaphoreCreateRecursiveMutex()

六、小结

    FreeRTOS的互斥量是保护共享资源的有效工具,具有以下特点:

  1. 提供对共享资源的独占访问

  2. 内置优先级继承机制,减少优先级反转的影响

  3. 使用简单,API接口清晰

  4. 适用于任务间的同步,但不适用于中断服务例程

    正确使用互斥量可以显著提高系统的稳定性和可靠性,但需要注意避免常见的陷阱如死锁、优先级反转等问题。在实际应用中,应根据具体场景选择合适的同步机制,平衡系统性能和资源保护的需求。

http://www.dtcms.com/a/321263.html

相关文章:

  • ctrl+alt+方向键导致屏幕旋转的解决方法
  • 基于双块轻量级神经网络的无人机拍摄的风力涡轮机图像去雾方法
  • No time to train! Training-Free Reference-Based Instance Segmentation之论文阅读
  • 机场风云:AI 云厂商的暗战,广告大战一触即发
  • 【实战】Dify从0到100进阶--中药科普助手(2)
  • 用browse实现菜单功能的方法
  • 快速上手 Ollama:强大的开源语言模型框架
  • Docker的安装使用以及常见的网络问题
  • 数据库恢复技术:保障数据安全的关键
  • DeepSeek辅助编写的带缓存检查的数据库查询缓存系统
  • Odoo 18 → Odoo 19 功能改动对比表
  • 基于Web的交互式坐标系变换矩阵计算工具
  • 时间复杂度计算(以for循环为例)
  • BBH详解:面向大模型的高阶推理评估基准与数据集分析
  • 轻松实现浏览器自动化——AI浏览器自动化框架Stagehand
  • 力扣 hot100 Day69
  • 使用 PicGo 与 GitHub 搭建高效图床,并结合 Local Images Plus 备份原图
  • 杂谈 001 · VScode / Copilot 25.08 更新
  • 供电架构之供电构型分类
  • 浪漫沙迦2|浪漫沙加2 七英雄的复仇 送修改器(Romancing SaGa 2)免安装中文版
  • 机器视觉任务(目标检测、实例分割、姿态估计、多目标跟踪、单目标跟踪、图像分类、单目深度估计)常用算法及公开数据集分享
  • excel 导出
  • 【vue】Vue 重要基础知识清单
  • Numpy科学计算与数据分析:Numpy广播机制入门与实践
  • 使用FinTSB框架进行金融时间序列预测的完整指南
  • 算法提升之-启发式并查集
  • 剪映里面导入多张照片,p图后如何再导出多张照片?
  • VScode 文件标签栏多行显示
  • QML中显示二级界面的三种方式
  • 【Git】企业级使用