一、什么是互斥量?
在多数情况下,互斥型信号量和二值型信号量非常相似,但是从功能上二值型信号量用于同步,
而互斥型信号量用于资源保护。
互斥型信号量和二值型信号量还有一个最大的区别,互斥型信号量可以有效解决优先级反转现
象。
什么是优先级翻转?
以上图为例,系统中有
3
个不同优先级的任务
H/M/L
,最高优先级任务
H
和最低优先级任务
L
通过
信号量机制,共享资源。目前任务
L
占有资源,锁定了信号量,
Task H
运行后将被阻塞,直到
Task
L
释放信号量后,
Task H
才能够退出阻塞状态继续运行。但是
Task H
在等待
Task L
释放信号量的过
程中,中等优先级任务
M
抢占了任务
L
,从而延迟了信号量的释放时间,导致
Task H
阻塞了更长时
间,这种现象称为优先级倒置或反转。
优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任
务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。
不过这个高优先级的任务
会将低优先级任务的优先级提升到与自己相同的优先级。
优先级继承并不能完全的消除优先级翻转的问题,它只是尽可能的降低优先级翻转带来的影响。
互斥量相关 API 函数

互斥型信号量的释放和获取与二值信号量完全相同 !


二、实操
实验需求
1.
演示优先级翻转
2.
使用互斥量优化优先级翻转问题
三、cubeMX配置
创建三个任务优先级依次降低
四、代码实现
/* USER CODE BEGIN Header_funH */
/**
* @brief Function implementing the taskH thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_funH */
void funH(void *argument)
{
/* USER CODE BEGIN funH */
/* Infinite loop */
for(;;)
{
//获取信号量
xSemaphoreTake(myMutex01Handle,portMAX_DELAY);
printf("Task H holds resources\r\n");
osDelay(2000);
//释放信号量
xSemaphoreGive(myMutex01Handle);
osDelay(1000);
}
/* USER CODE END funH */
}
/* USER CODE BEGIN Header_funM */
/**
* @brief Function implementing the taskM thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_funM */
void funM(void *argument)
{
/* USER CODE BEGIN funM */
/* Infinite loop */
for(;;)
{
printf("Task M uses cpu\r\n");
osDelay(1000);
}
/* USER CODE END funM */
}
/* USER CODE BEGIN Header_funL */
五、运行截图
最高优先级任务
H
和最低优先级任务
L
通过信号量机制,共享资源。当任务L
占有资源,锁定了信号量,
Task H
运行后将被阻塞,直到
TaskL释放信号量后,
Task H
才能够退出阻塞状态继续运行。但是
TaskH
在等待
Task L
释放信号量的过程中,中等优先级任务M
抢占了任务
L
,从而延迟了信号量的释放时间,导致
Task H
阻塞了更长时间,这种现象称为优先级倒置或反转。