freertos信号量之递归互斥信号量

freertos信号量之递归互斥信号量

简介

递归互斥信号量(Recursive Mutex Semaphore)是一种特殊类型的互斥信号量,允许持有互斥信号量的任务多次重新获取这个互斥信号量。以下是递归互斥信号量的常用函数及其说明:

1)xSemaphoreCreateRecursive()
创建一个递归互斥信号量。该函数接受一个无符号整型参数,用于指定递归互斥信号量的初始值。如果初始值为0,则表示递归互斥信号量未被占用;否则,表示递归互斥信号量已被占用。

2)xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex, portTickType xBlockTime)
获取递归互斥信号量。该函数会尝试获取递归互斥信号量,如果递归互斥信号量可用,则获取成功并立即返回;否则,如果递归互斥信号量不可用,函数会阻塞调用任务,直到递归互斥信号量可用或超时。xBlockTime参数指定阻塞时间,单位为系统时钟节拍数。

3)xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex)
释放递归互斥信号量。该函数会将递归互斥信号量的值加1,表示递归互斥信号量可用。如果有任务正在等待该递归互斥信号量,则其中一个任务将被唤醒并继续执行。

4)xSemaphoreGetCountRecursive(SemaphoreHandle_t xMutex)
获取递归互斥信号量的当前值。该函数返回递归互斥信号量的当前值,即0或大于0的一个整数。

使用递归互斥信号量注意点:

递归互斥信号量允许任务多次重新获取同一个信号量,因此可以用于需要多次进入临界区的场景。
递归互斥信号量的使用方式和普通互斥信号量类似,但需要注意避免死锁的情况。
持有递归互斥信号量的任务在进入临界区之前必须先获取该信号量,离开临界区之后必须释放该信号量。
需要注意的是,使用递归互斥信号量的任务在释放信号量时必须保证释放的是自己持有的那个信号量,否则可能导致其他任务无法获取到正确的信号量而引起死锁。

例如,如果一个任务成功获取了5次递归互斥信号量,那么该任务在后续的操作中还需要同样的释放5次递归互斥信号量。如果该任务没有正确释放已经获取的递归互斥信号量,其他任务就无法获取该信号量,从而导致了死锁的情况。

另外,递归互斥信号量和普通互斥信号量一样都具有优先级继承机制。如果一个低优先级的任务正在使用递归互斥信号量,而此时高优先级的任务也尝试获取该信号量的话,高优先级的任务就会阻塞等待。不过,高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,以尽可能的降低了高优先级任务处于阻塞态的时间,并降低因为“优先级翻转”所产生的影响。

例程

#include <FreeRTOS.h>  
#include <task.h>  
#include <mutex.h>  
  
// 定义递归互斥信号量的初始状态为0  
static MutexHandle_t recursiveMutex = 0;  
  
void vATask( void * pvParameters )  
{  
 portTickType xDelay;  
  
 for( ;; )  
 {  
 // 任务进入临界区,获取递归互斥信号量  
 xMutexTakeRecursive( recursiveMutex ); // 等待信号量变为0,阻塞状态最长时间为portMAX_DELAY  
 //临界区代码,访问共享资源  
 // ...  
 // 释放递归互斥信号量  
 xMutexGiveRecursive( recursiveMutex );  
  
 // 延时一定时间后再次进入临界区  
 xDelay = pdMS_TO_TICKS( 1000 ); // 延时1秒  
 portYIELD_WITHIN( xDelay );  
 }  
}

在上述示例中,任务vATask首先进入临界区并尝试获取递归互斥信号量。如果递归互斥信号量的值为零,任务会阻塞等待。一旦任务获取到递归互斥信号量,就可以访问共享资源。当任务完成对共享资源的访问后,释放递归互斥信号量,允许其他任务获取该资源。同时,任务进入临界区的代码执行完成后,会释放递归互斥信号量,以便其他任务可以获取该资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

付宇利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值