recursive mutex的使用场景和场景代码

递归互斥锁:允许一个任务获取多次锁,而不会导致任务挂起。

多层嵌套的函数调用中保护同一个资源

在一个复杂的软件模块中,可能存在多层函数调用,而最内层和最外层的函数都需要访问同一个共享资源(如外设、全局数据结构)。为了防止在调用过程中被其他任务抢占并破坏数据,每一层都可能需要加锁。

  • 问题所在:如果外层函数已经获取了普通互斥锁,然后调用了内层函数。内层函数再次尝试获取同一个锁时,会因为锁已被当前任务持有而阻塞,导致整个调用链卡死,形成死锁。

  • 解决方案:使用递归互斥锁,内层函数可以安全地再次获取锁,而不会阻塞。

SemaphoreHandle_t xRecursiveMutex;

// 底层硬件访问函数

void HAL_UART_WriteByte(uint8_t data) {

// 内层函数也需要加锁,确保操作的原子性

if (xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY) == pdTRUE) {

// 执行实际的UART寄存器操作

// USART_SendData(USART1, data);

xSemaphoreGiveRecursive(xRecursiveMutex);

}

}

// 上层逻辑函数

void vSendMessage(char *msg) {

// 外层函数先获取锁

if (xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY) == pdTRUE) {

// 发送字符串的每个字节

while (*msg) {

// 调用内层函数,它会再次获取同一个锁

HAL_UART_WriteByte(*msg++);

}

xSemaphoreGiveRecursive(xRecursiveMutex);

}

}

NOTE:

void HAL_UART_WriteByte(uint8_t data) 担心其他的地方会调用这个接口,导致最上层的没有xSemaphoreTakeRecursive没有锁住公共部分。这个时候就需要递归互斥锁。

递归函数中需要加锁

这是最典型、最直观的应用场景。当一个函数直接或间接地调用自身(递归)时,如果该函数内部需要获取同一个互斥锁来保护共享资源,就必须使用递归互斥锁。

  • 问题所在 :如果在递归函数中使用普通互斥锁,第一次调用时成功获取了锁,但在锁还未释放时,函数又调用了自身。第二次调用会尝试再次获取同一个锁,因为该锁已被当前任务持有,普通互斥锁会导致任务永久阻塞,即死锁。

  • 解决方案:递归互斥锁允许同一个任务多次"加锁",只需确保"解锁"次数与"加锁"次数相同即可。

// 假设有一个递归互斥锁句柄

SemaphoreHandle_t xRecursiveMutex;

// 递归函数,例如遍历树形结构

void vRecursiveFunction(int depth) {

// 每次进入函数都获取锁

if (xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY) == pdTRUE) {

// --- 临界区开始 ---

// 安全地访问或修改受保护的共享数据结构

// ...

// --- 临界区结束 ---

if (depth > 0) {

// 递归调用自身,此时会再次获取锁,但不会死锁

vRecursiveFunction(depth - 1);

}

// 每次退出函数都释放锁

xSemaphoreGiveRecursive(xRecursiveMutex);

}

}

相关推荐
@yanyu66610 小时前
C编译器安装与第一个C程序
c语言·开发语言
山下梅子酒22510 小时前
洛谷-入门-B2070
c语言
Logic10110 小时前
C语言/数据结构位运算题解:异或XOR找出多任务下载器中的“独特下载速度“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
MI_farmer12 小时前
Anaconda 安装在 D 盘但虚拟环境跑到 C 盘,以及 Conda PermissionError: WinError 5 的解决方法
c语言·开发语言·conda
心中有你021414 小时前
C语言 二叉搜索树(BST)超详细完整实现(插入+查找+删除+三种遍历+内存释放)
c语言
神仙别闹14 小时前
基于C语言实现 TINY+ 编译器
c语言·开发语言·数据库
共享家952715 小时前
C语言-408
c语言·开发语言
ACP广源盛1392462567317 小时前
接口适配方案选型|GSV6125@ACP HDMI2.0 转 Type‑C/DP1.4 桥接芯片工程评估
大数据·c语言·开发语言·硬件架构·硬件工程·国产芯片
芯祥联20 小时前
STM32 上跑 MQTT 怎么选?嵌入式 MQTT 客户端 C 语言实现对比
c语言·stm32·单片机·嵌入式硬件·网络协议·开源·broker
Escalating_xu1 天前
【C 语言】深入理解指针(1·下):指针运算、野指针、assert 与传址实战
java·c语言·开发语言