FreeRTOS_互斥量(Mutex)

1、互斥量特性

互斥量是一种特殊的二进制信号量。

每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束后解锁。
资源还是共享的,线程间也还是竞争的,但通过锁将资源的访问变为互斥操作,而后与时间有关的错误也不会在产生了。
注意:同一个时刻,只能有一个线程持有该锁。

在这里插入图片描述
在有多线程访问共享资源时使用。

2、互斥量函数

使用互斥量时,先创建,然后获取,再释放。

2.1、互斥量创建

要想使用互斥量,需要在配置文件FreeRTOSsConfig.h中定义:

#define configUSE_MUTEXES 1
  • 动态创建
//函数内部会同台分配互斥量结构体
SemaphoreHandle_t xSemaphoreCreateMutex( void );
参数描述
返回值成功则返回句柄
  • 静态创建
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
参数描述
pxMutexBuffer创建一个StaticSemaphore_t类型 结构体,用来保存信号量结构体
返回值成功则返回句柄

2.2、获取、释放、删除互斥量

互斥量是一种特殊的信号量,所以获取、释放、删除的API基本和信号量的通用。
互斥量的获取、释放一般不在中断中执行,所以此处无FromISR结尾函数。

/*
 * xSemaphore: 信号量句柄,你要删除哪个信号量, 互斥量也是一种信号量
 * 删除互斥量
 */
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

/* 释放 */
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

/* 获得 */
BaseType_t xSemaphoreTake(
                   SemaphoreHandle_t xSemaphore,
                   TickType_t xTicksToWait
               );

3、互斥锁的优先级反转和优先级继承

  • 互斥锁的优先级反转是指在多线程环境下,一个低优先级的任务持有了一个高优先级任务需要的资源(低优先级持有一把互斥锁,此时有高优先级任务需要获取同一把锁),导致高优先级任务无法继续执行的情况。这种情况下,低优先级任务会"反转"成为当前的”最高优先级“任务,从而延迟了高优先级任务的执行。
  • 优先级继承是当一个高优先级任务请求锁时,如果该锁已经被低优先级任务所持有,那么低优先级任务的优先级会被提升到高优先级任务的优先级,以保证高优先级任务能够及时地访问资源并完成工作。一旦低优先级任务释放了锁,其优先级会恢复到原来的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在任务系统中,多个任务可能会同时访问共享资源,如果不加控制地访问共享资源,就会导致数据不一致等问题。互斥Mutex)是一种用于保护共享资源的FreeRTOS内核对象,它可以保证在任意时刻只有一个任务能够访问共享资源,从而避免了数据不一致等问题。 互斥的作用主要有两个方面: 1. 保护共享资源:当一个任务获得了互斥之后,其他任务就无法获得该互斥,直到该任务释放了互斥。这样就可以保证在同一时间内只有一个任务能够访问共享资源,从而避免了数据不一致等问题。 2. 防止任务饥饿:任务饥饿是指某个任务无法获得所需的资源而一直处于等待状态。如果多个任务同时竞争某个共享资源,且没有互斥保护,那么可能会导致某个任务一直无法获得该资源而一直处于等待状态,从而导致任务饥饿。互斥可以避免这种情况的发生,因为只有获得了互斥的任务才能访问共享资源,其他任务只能在等待队列中等待,不会一直处于等待状态。 下面是一个简单的使用互斥的示例代码: ```c #include "FreeRTOS.h" #include "task.h" #include "semphr.h" // 共享资源 int shared_data = 0; // 互斥 SemaphoreHandle_t mutex; // 任务1 void vTask1(void *pvParameters) { while(1) { xSemaphoreTake(mutex, portMAX_DELAY); // 获取互斥 shared_data++; // 访问共享资源 xSemaphoreGive(mutex); // 释放互斥 vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时1秒 } } // 任务2 void vTask2(void *pvParameters) { while(1) { xSemaphoreTake(mutex, portMAX_DELAY); // 获取互斥 shared_data--; // 访问共享资源 xSemaphoreGive(mutex); // 释放互斥 vTaskDelay(2000 / portTICK_PERIOD_MS); // 延时2秒 } } int main() { // 创建互斥 mutex = xSemaphoreCreateMutex(); // 创建任务1 xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, 1, NULL); // 创建任务2 xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, 2, NULL); // 启动任务调度器 vTaskStartScheduler(); // 不会执行到这里 return 0; } ``` 在这个示例中,我们创建了一个共享资源shared_data,并使用互斥mutex来保护它。在任务1和任务2中,都使用了xSemaphoreTake函数获取互斥mutex,然后访问共享资源shared_data,最后使用xSemaphoreGive函数释放互斥mutex。这样就保证了在同一时间内只有一个任务能够访问共享资源shared_data,从而避免了数据不一致等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值