当前位置: 首页 > 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.lryc.cn/news/613800.html

相关文章:

  • linux添加自启动
  • wodpress结构化数据对SEO的作用
  • simulink tlc如何通过tlc写数据入文件
  • 基于UDP的代理协议的Tuic怎么样?
  • GoLand 项目从 0 到 1:第六天 —— 权限接口开发与问题攻坚
  • 构建响应式在线客服聊天系统的前端实践 Vue3+ElementUI + CSS3
  • 走进Linux世界:make和makefile
  • Seaborn 学习笔记
  • LINUX-用户及用户组管理
  • 【嵌入式】记录一次网络转串口透传性能提升的过程
  • 【Linux系统】万字解析,文件IO
  • Android 系统的安全 和 三星安全的区别
  • 华为USG防火墙双机,但ISP只给了1个IP, 怎么办?
  • 5. 缓存-Redis
  • 【Android笔记】Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)
  • 考研复习-计算机组成原理-第四章-指令系统
  • wstool和git submodule优劣势对比
  • WinForm 对话框的 Show 与 ShowDialog:阻塞与非阻塞的抉择
  • qt中实现QListWidget列表
  • GUI:QT简介
  • C# GUI程序中的异步操作:解决界面卡顿的关键技术
  • 频谱图学习笔记
  • HTTP 请求返回状态码和具体含义?200、400、403、404、502、503、504等
  • Docker搭建Jenkins实现自动部署:快速高效的持续集成之道!
  • 五十五、【Linux系统nginx服务】nginx安装、用户认证、https实现
  • 芯伯乐XBL6019 60V/5A DC-DC升压芯片的优质选择
  • 查看泰山派 ov5695研究(1)
  • 【重磅发布】flutter_chen_keyboard -专注于键盘相关功能
  • MFC扩展库BCGControlBar Pro v36.2:MSAA和CodedUI测试升级
  • Kotlin 数据容器 - MutableList(MutableList 概述、MutableList 增删改查、MutableList 遍历元素)