FreeRTOS ~(七)互斥量 ~ (2/3)互斥量解决优先级反转问题

前情提要
FreeRTOS ~(四)同步互斥与通信 ~ (2/3)互斥的缺陷
FreeRTOS ~(五)队列的常规使用 ~ (2/5)队列解决互斥缺陷
FreeRTOS ~(六)信号量 ~ (2/3)信号量解决互斥缺陷
FreeRTOS ~(七)互斥量 ~ (1/3)互斥量解决互斥缺陷
互斥量解决优先级反转问题

上述的几篇文章说明了互斥的缺陷及一些解决方法,但是却没有解决一个问题:
互斥的两个任务的优先级反转问题.
为了说明说明是优先级反转,这里设置一个例子来实际操作一下;
举例说明:
创建三个任务,优先级不同,
如:
高优先级的优先级是3;
中优先级的优先级是2;
低优先级的优先级是1;
高优先级与低优先级都要使用到信号量,而中优先级不使用信号量,这里使用二值信号量来解决互斥问题;
高优先级执行后主动让自己Dealy 10ms,然后去获取信号量(take)
中优先级执行后主动让自己Delay 30ms,
低优先级任务则先获取信号量(take),然后执行一段较为耗时的打印工作,执行完成后,释放信号量(give)
通过设置相应的标志位(Flag),利用逻辑分析仪来观察Task执行情况.
代码如下:
static volatile uint8_t flagLPTaskRun = 0;	/* 低优先级任务执行标志位 */
static volatile uint8_t flagMPTaskRun = 0;	/* 中优先级任务执行标志位 */
static volatile uint8_t flagHPTaskRun = 0;	/* 高优先级任务执行标志位 */
static void vLPTask( void *pvParameters );	/* 低优先级任务声明 */
static void vMPTask( void *pvParameters );	/* 中优先级任务声明 */
static void vHPTask( void *pvParameters );	/* 高优先级任务声明 */
/*-----------------------------------------------------------*/
/* 互斥量/二进制信号量句柄 */
SemaphoreHandle_t  xLock;
/*-----------------------------------------------------------*/
int main( void )
{prvSetupHardware();/* 创建互斥量/二进制信号量 */xLock = xSemaphoreCreateBinary();xSemaphoreGive(xLock);if( xLock != NULL ){/* 创建3个任务: LP,MP,HP(低/中/高优先级任务) */xTaskCreate( vLPTask, "LPTask", 1000, NULL, 1, NULL );xTaskCreate( vMPTask, "MPTask", 1000, NULL, 2, NULL );xTaskCreate( vHPTask, "HPTask", 1000, NULL, 3, NULL );/* 启动调度器 */vTaskStartScheduler();}else{/* 无法创建互斥量/二进制信号量 */}/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */return 0;
}
/*-----------------------------------------------------------*/
static void vLPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 10UL );	uint32_t i;char c = 'A';printf("LPTask start\r\n");/* 无限循环 */for( ;; ){	/* 标志位表明正在执行的任务是低优先级任务 */flagLPTaskRun = 1;flagMPTaskRun = 0;flagHPTaskRun = 0;/* 获得互斥量/二进制信号量 */xSemaphoreTake(xLock, portMAX_DELAY);/* 耗时很久 */printf("LPTask take the Lock for long time");for (i = 0; i < 500; i++) {flagLPTaskRun = 1;flagMPTaskRun = 0;flagHPTaskRun = 0;printf("%c", c + i);}printf("\r\n");/* 释放互斥量/二进制信号量 */xSemaphoreGive(xLock);vTaskDelay(xTicksToWait);}
}
/*-----------------------------------------------------------*/
static void vMPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 30UL );	flagLPTaskRun = 0;flagMPTaskRun = 1;flagHPTaskRun = 0;printf("MPTask start\r\n");/* 让LPTask、HPTask先运行 */	vTaskDelay(xTicksToWait);/* 无限循环 */for( ;; ){	/* 标志位表明正在执行的任务是中优先级任务 */flagLPTaskRun = 0;flagMPTaskRun = 1;flagHPTaskRun = 0;}
}
/*-----------------------------------------------------------*/
static void vHPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 10UL );	/* 标志位表明正在执行的任务是高优先级任务 */flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;printf("HPTask start\r\n");/* 主动进入阻塞态,10ms,让LPTask先运行 */	vTaskDelay(xTicksToWait);/* 无限循环 */for( ;; ){	flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;printf("HPTask wait for Lock\r\n");/* 获得互斥量/二进制信号量 */xSemaphoreTake(xLock, portMAX_DELAY);flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;/* 释放互斥量/二进制信号量 */xSemaphoreGive(xLock);}
}
/*-----------------------------------------------------------*/

优先级反转说明

如何解决优先级反转这个问题呢?
抛弃二值信号量,使用互斥量,下面简单修改一下代码即可,因为互斥量也是特殊的信号量,使用的一些API函数是一致的,
这里只需要将信号量的创建由二进制信号量,更换为互斥量即可.
int main( void )
{prvSetupHardware();/* 创建互斥量/二进制信号量 */#if  0xLock = xSemaphoreCreateBinary();xSemaphoreGive(xLock);#elsexLock = xSemaphoreCreateMutex();#endifif( xLock != NULL ){/* 创建3个任务: LP,MP,HP(低/中/高优先级任务) */xTaskCreate( vLPTask, "LPTask", 1000, NULL, 1, NULL );xTaskCreate( vMPTask, "MPTask", 1000, NULL, 2, NULL );xTaskCreate( vHPTask, "HPTask", 1000, NULL, 3, NULL );/* 启动调度器 */vTaskStartScheduler();}else{/* 无法创建互斥量/二进制信号量 */}/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */return 0;
}

优先级继承

解决优先级反转的问题,互斥量使用的方法使优先级继承.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15597.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

swiftUI和swift的区别

概述 SwiftUI是苹果公司推出的一种用于构建iOS、macOS、watchOS和tvOS应用程序界面的框架。它是基于Swift编程语言开发的&#xff0c;旨在简化UI开发过程并提供实时预览功能&#xff0c;使开发人员可以更快地构建出漂亮的应用程序界面。 Swift是苹果公司推出的一种面向对象的…

Openlayers实战:overlay上播放视频

在企业或者城市等的宣传上,视频能很好的传达出一些信息。 那么在openlayer中如何展示视频呢, 可以通过overlay的方式,点击某一个点,弹出overlay层,展示出视频,并自动播放。下面的实战就能够达到这种效果。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还…

OPPO手机便签怎么设置字体颜色?便签调整字体颜色方法

OPPO是一个非常受年轻人青睐的手机品牌&#xff0c;它的手机不仅外观设计时尚轻薄&#xff0c;而且拍照清晰、系统流畅&#xff0c;并且拥有高中低不同档次的价位可供消费者选择。虽然OPPO手机的使用体验非常不错&#xff0c;但是有一部分用户也遇到了一些问题&#xff0c;例如…

牛客小白月赛75 DE

D 矩阵 登录—专业IT笔试面试备考平台_牛客网 思路&#xff1a;我们能够发现每个点最多只用两种状态&#xff0c;一种是不变&#xff0c;另一种是改变&#xff0c;如果相邻的点与当前点不相同&#xff0c;则可以花费一个单位走过去&#xff0c;否则需要先改变它的状态&#x…

第2集丨JavaScript 中原型链(prototype chain)与继承

目录 一、一些基础概念1.1 ECMAScript 标准1.2 prototype和 __proto__1.3 constructor属性1.4 函数名 二、原型链的维护2.1 内部原型链和构造器原型链2.2 从实例回溯原型链2.3 修正原型指向 三、基于原型链的继承3.1 继承属性3.2 继承“方法” 四、构造函数4.1 案例一个简单的实…

Android加快你的编译速度

工欲善其事&#xff0c;必先利其器。如果每次运行项目都要花费5-10分钟&#xff0c;那人的心态都要崩了。 Gradle构建流程 Gradle 的生命周期可以分为大的三个部分&#xff1a;初始化阶段&#xff08;Initialization Phase)&#xff0c;配置阶段&#xff08;Configuration Pha…

Linux性能优化实践——CPU上下文

CPU上下文切换 Linux是一个多任务操作系统&#xff0c;它支持远大于CPU数量的任务同时运行。这些任务不是真正意义上的并行运行&#xff0c;而是系统在短时间内&#xff0c;将CPU轮流分配给它们&#xff0c;造成任务同时运行的错觉。 CPU需要知道任务从哪里加载&#xff0c;从…

Elasticsearch【域的属性、分词器、Elasticsearch搜索文档】(三)-全面详解(学习总结---从入门到深化)

目录 Elasticsearch常用操作_域的属性 分词器_默认分词器 分词器_IK分词器 分词器_拼音分词器 分词器_自定义分词器 Elasticsearch搜索文档_准备工作 Elasticsearch搜索文档_搜索方式 Elasticsearch常用操作_域的属性 index 该域是否创建索引。只有值设置为true&#…

CCF-CSP真题《202303-4 星际网络II》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202303-4试题名称&#xff1a;星际网络II时间限制&#xff1a;2.0s内存限制&#xff1a;1.0GB问题描述&#xff1a; 问题描述 随着星际网络的进一步建设和规模的增大&#x…

Android Studio实现内容丰富的安卓视频管理平台

如需源码可以添加q-------3290510686&#xff0c;也有演示视频演示具体功能&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号081 1.开发环境 android stuido 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.本地视频 3.视频播放 4.收藏功能 5.网路视频…

016 - STM32学习笔记 - SPI读写FLASH(一)

016 - STM32学习笔记 - SPI访问Flash&#xff08;一&#xff09; 之前csdn的名称是宥小稚&#xff0c;后来改成放学校门口见了&#xff0c;所以前面内容看到图片水印不要在意&#xff0c;都是自己学习过程中整理的&#xff0c;不涉及版权啥的。 1、什么是SPI&#xff1f; SP…

LabVIEW FPGA利用响应式数字电子板快速开发空间应用程序

LabVIEW FPGA利用响应式数字电子板快速开发空间应用程序 与传统的基于文本的语言相比&#xff0c;LabVIEW的编程和设计已被证明可以缩短开发时间。各种研究表明&#xff0c;生产率的提高在3到10倍之间。LabVIEW通过图形语言、集成开发环境和多个编译器的组合来实现这一点。 图…