FreeRTOS(5)----互斥量

news2024/11/25 4:43:03

一,互斥信号量

互斥信号量是一个具有优先级继承的二值信号量,在同步的应用中二值信号量最合适。互斥信号量适合互斥访问的那些应用。在互斥访问中互斥信号量相当于一个钥匙,当一个任务使用这个资源,资源就会被上锁,防止其他资源去使用它,当这个任务使用完毕,就会开锁,然后别的任务就可以访问该资源。但这样存在一个任务优先级翻转的问题,需要优先级继承算法来解决。

二,优先级翻转

优先级继承算法指的是暂时提高某个占用某种资源的低优先级的任务,使得在等待该资源的任务中优先级最高的任务优先级相等,当原本占有资源的任务释放了资源后,优先级恢复为原来的设定值。在系统中,一般高优先级的任务就代表了这个任务越重要,越要优先执行,但在互斥访问中,高优先级任务访问的资源被上锁,导致变为挂起态,在freertos中,紧急的任务无法得到快速处理,则会对系统产生很大的危害。

当一个低优先级的任务占用一个资源,当前资源被上锁。当高优先级的任务来访问,因为资源被上锁,所以它要进入阻塞态【在这里选择阻塞态还是挂起态,其实要根据实际情况而定,当在多任务共享资源的情境下,当两个任务同时访问一个资源的时候,且当前的资源被另外一个任务占领,另外两个任务就会进入阻塞态,不断的进行自旋等待,不断的访问信号量,当信号量来了,再转为就绪态,这样可能会存在卡死的情况,如果进入的是挂起态,任务会释放CPU,当资源被释放的时候,任务再被唤醒,转为就绪态等待被调度,这样避免了无限扽等待以及卡死的情况,所以在多任务共享资源下,挂起态则是更优选】,此时优先级的继承机制就要发挥作用了,把当前占用资源的低优先级的任务提升到和高优先级任务一样的优先级。这样可以确保高优先级的任务提早进入阻塞态。

·任务L正常运行,占用资源。

·任务H想访问资源,任务H优先级高于L,但是呢,因为任务L将资源上锁,所以任务H只能进入阻塞态

·任务M因为优先级高于任务L,会抢占CPU的使用权,当任务M完成后,任务L继续运行

·当任务L运行结束,释放资源,任务H才开始运行,这相当于任务H的优先级低于任务M了,任务H的阻塞时间相当于是任务L的运行时间+任务M的运行时间。

优化:当任务H也需要使用这个共享资源的时候,将任务L的优先级提升到和任务H一样的优先级,这样任务L就不会被抢占,间接可以让任务H的阻塞时间变短,任务H的阻塞时间只有任务L的运行时间。

但我也有了一个疑问,当任务M的优先级高于任务H的时候,这样提升优先级的意义好像没啥必要,所以去问了一下chatGPT3.5。

额外注意的是,互斥量只可以用于任务之间,不可以在中断内使用。 

三,互斥量的应用场景

1.共享资源:当多个任务访问同一资源,需要使用互斥量来保证只有一个任务来访问当前的资源。

2.临界区:当多个任务再进入代码的共享区域的时候,需要使用互斥量来保护临界区,确保同一时刻的临界区只可以被一个任务访问。

3.任务队列:当多个线程需要从同一个任务队列获取任务并且执行的时候,需要使用互斥量来保证同一时刻只有一个线程可以访问任务队列。

优先级翻转代码理解:

进入高优先级任务,但是立马就被阻塞了

//高优先级任务的任务函数
void high_task(void *pvParameters)
{
	u8 num;
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"High Task");
	
	while(1)
	{
		vTaskDelay(500);	//延时500ms,也就是500个时钟节拍	
		num++;
		printf("high task Pend Sem\r\n");
		xSemaphoreTake(MutexSemaphore,portMAX_DELAY);	//获取互斥信号量
		printf("high task Running!\r\n");
		LCD_Fill(6,131,114,313,lcd_discolor[num%14]); 	//填充区域
		LED1=!LED1;
		xSemaphoreGive(MutexSemaphore);					//释放信号量
		vTaskDelay(500);	//延时500ms,也就是500个时钟节拍  
	}
}

 CPU运行中优先级任务,在阻塞阶段运行低优先级任务,低优先级任务获取信号量,且未释放,高优先级任务抢占低优先级任务,却无法获得信号量进入阻塞阶段,导致不断的打印“middle task Running!”,只有在中优先级任务阻塞阶段,低优先级释放了信号量,高优先级才会被执行

//中等优先级任务的任务函数
void middle_task(void *pvParameters)
{
	u8 num;
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(125,110,234,314); //画一个矩形	
	LCD_DrawLine(125,130,234,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Middle Task");
	while(1)
	{
		num++;
		printf("middle task Running!\r\n");
		LCD_Fill(126,131,233,313,lcd_discolor[13-num%14]); //填充区域
		LED0=!LED0;
        vTaskDelay(1000);	//延时1s,也就是1000个时钟节拍	
	}
}

//低优先级任务的任务函数
void low_task(void *pvParameters)
{
	static u32 times;

	while(1)
	{
		xSemaphoreTake(MutexSemaphore,portMAX_DELAY);	//获取互斥信号量
		printf("low task Running!\r\n");
		for(times=0;times<5000000;times++)				//模拟低优先级任务占用互斥信号量
		{
			taskYIELD();								//发起任务调度
		}
		xSemaphoreGive(MutexSemaphore);					//释放互斥信号量
		vTaskDelay(1000);	//延时1s,也就是1000个时钟节拍
	}
}

 

 

互斥量实验代码理解:

虽然后才开始优先级高的先执行,但是在循环的时候进行了阻塞

//高优先级任务的任务函数
void high_task(void *pvParameters)
{
	u8 num;
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"High Task");
	
	while(1)
	{
		vTaskDelay(500);	//延时500ms,也就是500个时钟节拍	
		num++;
		printf("high task Pend Sem\r\n");
		xSemaphoreTake(MutexSemaphore,portMAX_DELAY);	//获取互斥信号量
		printf("high task Running!\r\n");
		LCD_Fill(6,131,114,313,lcd_discolor[num%14]); 	//填充区域
		LED1=!LED1;
		xSemaphoreGive(MutexSemaphore);					//释放信号量
		vTaskDelay(500);	//延时500ms,也就是500个时钟节拍  
	}
}

所以先运行中优先级,在中优先级阻塞的时候,运行低优先级【此时高优先级还在延时等待】,低优先级获取信号量,此时高优先级转为就绪态,抢占低优先级,但低优先级的任务被提升到和互斥优先级任务一样的优先级,所以不会打印“middle task Running!”,当低优先级释放信号量后,高优先级直接开始运行。

//中等优先级任务的任务函数
void middle_task(void *pvParameters)
{
	u8 num;
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(125,110,234,314); //画一个矩形	
	LCD_DrawLine(125,130,234,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Middle Task");
	while(1)
	{
		num++;
		printf("middle task Running!\r\n");
		LCD_Fill(126,131,233,313,lcd_discolor[13-num%14]); //填充区域
		LED0=!LED0;
        vTaskDelay(1000);	//延时1s,也就是1000个时钟节拍	
	}
}

//低优先级任务的任务函数
void low_task(void *pvParameters)
{
	static u32 times;

	while(1)
	{
		xSemaphoreTake(MutexSemaphore,portMAX_DELAY);	//获取互斥信号量
		printf("low task Running!\r\n");
		for(times=0;times<5000000;times++)				//模拟低优先级任务占用互斥信号量
		{
			taskYIELD();								//发起任务调度
		}
		xSemaphoreGive(MutexSemaphore);					//释放互斥信号量
		vTaskDelay(1000);	//延时1s,也就是1000个时钟节拍
	}
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[CTF/网络安全] 攻防世界 robots 解题详析

[CTF/网络安全] 攻防世界 robots 解题详析 robots.txt姿势总结 题目描述&#xff1a;X老师上课讲了Robots协议&#xff0c;小宁同学却上课打了瞌睡&#xff0c;赶紧来教教小宁Robots协议是什么吧。 进入靶机&#xff0c;页面空白。 查看页面源代码&#xff1a; 再次结合题目Rob…

Java常用工具之StringUtils类

目录 一、字符串判空二、分隔字符串三、判断是否为纯数字四、将集合拼接成字符串五、其他方法 字符串&#xff08;String&#xff09;在我们的日常工作中&#xff0c;用得非常非常非常多。 在我们的代码中经常需要对字符串判空&#xff0c;截取字符串、转换大小写、分隔字符串、…

chatgpt赋能Python-python3_取模

Python3 取模&#xff1a;介绍与使用 在Python3中&#xff0c;取模运算是比较常用的运算符。本文将介绍Python中的取模运算符&#xff0c;并分享多种使用取模运算符的方法。 什么是取模运算符 在数学上&#xff0c;取模运算是将一个整数除以另一个整数&#xff0c;然后返回相…

后端传到前端的JSON数据大写变小写--2023

问题复现&#xff1a;1. 首先我先说一下&#xff0c;我用了lombok&#xff0c;事实证明和这个也有关系 前端这里写的也是按照驼峰命名来写的 控制台打印出来的数据 后台打印出来的数据 解决方法&#xff1a; 1. 重写get/set方法 因为我在实体类上标注了Data注解 重写get/se…

电动力学专题:闵氏几何(伪欧几何)

相对性原理和光速不变 物理定律在所有的惯性参考系里都是平等的&#xff0c;不存在一个特殊的惯性系。真空中的光速在所有的惯性系里都是一样的。 洛伦兹变换 距离度量&#xff1a;闵氏(Mins geometry) 狭义相对论下&#xff0c;不随惯性系变化的量闵式距离&#xff08;时空间…

HNU数据结构与算法分析-作业2-线性结构

1. (简答题) 4.1 假设一个线性表包含下列元素&#xff1a; <|2,23,15,5,9> 使用Shaffer编写的教材《数据结构与算法分析》的List ADT编写一些C语句&#xff0c;删除值为15的元素。 &#xff08;要求&#xff1a;采用C或C语言描述算法&#xff09; 4.6 使用Shaffer编写…

[CTF/网络安全] 攻防世界 cookie 解题详析

[CTF/网络安全] 攻防世界 cookie 解题详析 HTTP响应的查看方法method 1method 2 总结 题目描述&#xff1a;X老师告诉小宁他在cookie里放了些东西&#xff0c;小宁疑惑地想&#xff1a;这是夹心饼干的意思吗&#xff1f; 根据提示&#xff0c;获取页面Cookie中的数据即可 页面提…

学生成绩信息管理系统

系列文章 任务2 学生成绩信息管理系统 文章目录 系列文章一、实践目的与要求1、目的2、要求 二、课题任务三、总体设计1.存储结构及数据类型定义2.程序结构3.所实现的功能函数4、程序流程图 四、小组成员及分工五、 测试score.txtbk.txt界面展示显示所有学生信息添加学生信息删…

【数据结构】数据结构中的栈

文章目录 前言什么是栈栈的实现栈的初始化入栈出栈栈的判空栈内有效数据个数返回栈顶数据栈的销毁 前言 该篇文章来了解数据结构中的栈&#xff0c;栈与队列都为一种线性存储结构&#xff0c;同时栈与队列在逻辑结构上&#xff0c;都只能在头或者尾进行对数据的操作&#xff1…

25 KVM管理虚拟机-虚拟机安全启动

文章目录 25 KVM管理虚拟机-虚拟机安全启动25.1 总体介绍25.1.1 概述25.1.2 功能说明25.1.3 约束限制 25.2 安全启动实践25.2.1 虚拟机配置25.2.2 证书导入25.2.3 安全启动观测 25 KVM管理虚拟机-虚拟机安全启动 25.1 总体介绍 25.1.1 概述 安全启动&#xff08;Secure Boot…

基于JAVA的高校宿舍管理系统的设计与实现(论文+源码)_kaic

目 录 1 绪论 1.1 研究背景 1.2 研究目的和意义 1.3 课题任务 1.4 本文结构 2 开发工具及技术介绍 2.1 开发工具介绍 2.2 开发技术介绍 3 系统分析 3.1 可行性分析 3.2 需求分析 4 系统设计 4.1 系统结构设计 4.2 系统功能模块设计 4.3 业务时序设计 4.4 住宿流程设计 4.5 数…

CSS-预编译器-Sass

前言 Sass 是一款强化 CSS 的辅助工具&#xff0c;它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能&#xff0c;这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库&#xff08;如 Compass&am…

【MySQL】MySQL基础知识详解

文章目录 1. MySQL概述1.1 数据库相关概念1.1.1 数据库、数据库管理系统与SQL1.1.2 关系型数据库与数据模型 1.2 MySQL数据库1.2.1 MySQL的安装与配置1.2.2 MySQL服务的启动与停止1.2.3 连接MySQL服务端 2. SQL2.1 SQL简介2.2 DDL2.2.1 数据库操作2.2.2 表操作2.2.2.1 创建表2.…

无任何格外需求的命令行C++飞机大战,内含BOSS,动画,万行代码!免费奉上!

个程序的源码没有什么技术要求&#xff0c;一般至少能看懂95%&#xff0c;因为博主是大一上学期写着玩的&#xff0c;当写了一周&#xff0c;还拿它参加了学校的创意编程比赛&#xff0c;结果第一用的ui&#xff0c;直接降维打击了&#xff0c;拿了个二等奖 操作方法游戏内都有…

OAuth2.0 OIDC1.0及落地方案

目录 一、导语二、初识OAuth2.0三、OAuth2.0四、OIDC1.0五、OAuth2.0 & OIDC1.0授权模式选型建议六、典型架构及示例6.1 用户认证中心6.2 客户端6.3 应用网关6.4 后端API服务 七、附录- OAuth & OIDC常用端点 一、导语 应用的使用离不开用户&#xff0c;所以用户认证与…

缓存架构设计Spring对于Cache的抽象架构

目录 缓存架构设计 JSR107 JSR107核心接口 JSR107图示 Spring对于Cache的抽象架构 介绍 Cacheable CachePut CacheEvict CacheConfig 缓存架构设计 JSR107 首先&#xff0c;来了解一下JSR107规范JSR是Java Specification Requests 的缩写 &#xff0c;Java规范请求&…

chatgpt赋能Python-python3_ljust

Python 3 ljust - 实现字符串长度对齐的神器 在Python 3中&#xff0c;ljust()是一个非常常用的字符串方法。它可以方便地对齐字符串&#xff0c;并添加左对齐的填充字符。无疑&#xff0c;它是Python编程中不可缺少且十分实用的工具神器。 什么是ljust()&#xff1f; ljust…

MybatisPlus数据层标准的CRUD(增删改查)的实现与分页功能

文章目录 1 标准CRUD使用2 新增3 删除4 修改5 根据ID查询6 查询所有7 Lombok步骤1:添加lombok依赖步骤2:安装Lombok的插件步骤3:模型类上添加注解 8 分页功能步骤1:调用方法传入参数获取返回值步骤2:设置分页拦截器步骤3:运行测试程序 在这一节中我们重点学习的是数据层标准的C…

每日练习---C语言

目录 前言&#xff1a; 1.打印菱形 1.1补充练习 2.打印水仙花 2.1补充训练 前言&#xff1a; 记录博主做题的收获&#xff0c;以及提升自己的代码能力&#xff0c;今天写的题目是&#xff1a;打印菱形、打印水仙花数。 1.打印菱形 我们先看到牛客网的题&#xff1a;OJ链…

利用ChatGPT编写Excel公式,对比讯飞星火与ChatGPT对Excel公式的回答

系列文章目录 借助国内ChatGPT平替MindShow&#xff0c;飞速制作PPT 借助国内ChatGPT平替markmap/Xmind飞速生成思维导图 借助国内ChatGPT平替剪映/百度AIGC平台快速制作短视频 文章目录 系列文章目录前言一、利用ChatGPT编写Excel公式1.描述我们想实现的Excel公式&#xff…