FreeRTOS内部机制学习02(消息队列深度学习)

news2024/12/23 5:10:32

文章目录

  • 队列的核心以及好处
    • 队列的核心
    • 队列的好处
  • 深入源码了解队列机制
    • 深入队列读取操作
    • 深入队列写入操作
    • 读写队列出超时时间
  • 信号量
    • 深入信号量获取以及释放操作
  • 互斥量
    • 互斥量和信号量的不同
    • 深入源码看优先级继承是怎么操作到的

队列的核心以及好处

队列的核心

队列的核心就是关中断环形缓冲区链表
从而做到互斥访问数据。
在这里插入图片描述如果队列函数就仅仅是这样关中断的话,那我们不就可以自己手写了吗,那队列好像也没有什么厉害的地方,其实不然,使用队列还有很多的好处。

队列的好处

我们想象一个场景:
在这里插入图片描述
那这里就显示出了队列的好处了,队列就可以大显身手了!
在这里插入图片描述
使用队列的话,判断了一次之后任务就会休眠,这样不就大大减少了时间吗,提升了CPU的运行速度!直到符合条件了,就会主动地去唤醒它。
在这里插入图片描述

深入源码了解队列机制

上面说的这么简单,B任务没有读到数据就休眠,休眠内部代码具体是怎么做到的,具体可以看我的上一篇文章:任务的内部机制
那么,发送信息的任务A是怎么知道是去唤醒的是任务B的呢?
其实在创建队列的时候,里面的操作,产生了两个特定的链表,读写队列,都会有写满或者没数据的情况,遇到这两种情况,毋庸置疑,任务都是会休眠的,那到时候别人来唤醒它的时候,怎么找得到它呢?这个时候,这两个链表就发挥了作用!
创建队列的时候生成了一个结构体,上面所说的东西以及其他没有说到的东西都包含在里面:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

休眠了,就会把自己的任务的TCB结构体记录在上面这两个链表里面,到时候就会去这两个链表里面找!
假如没数据可读了,那么读任务就会休眠,等到别的任务来唤醒它的时候,就会去其中一个链表里面找,那么另外一种情况,亦是如此!
在这里插入图片描述

深入队列读取操作

主要操作:
在这里插入图片描述
因为遇到没有数据的情况下,读取数据是可以选择的等待的,想要等待你就乖乖休眠,把你的任务的TCB写入到Delay链表中,然后在队列链表中登记一下,到时候有数据了第一时间叫你,你要是没有耐心等到的话就走吧,下图所示:
在这里插入图片描述
成功读取到了数据了,还要干什么吗?
成功读取到了数据了;那么队列就会有空出来的位置了,可能在我没有读取出来之前可能有一个写任务想要写,但是由于没有位置了但是他很有耐心,选择了等待,那么他就会进入休眠状态,并且在List_t xTaskswaitingToSend链表处登记了一下,那我成功了读取了数据腾出空间来了,我就会去那个链表看看你是否还在那里,在的话就优先让你写!
为什么要关闭中断呢?
一个工程中难免会有多个任务一起来读同一个队列,所以每次轮到谁来读取了,肯定要吃独食啊,不然我读一半,你突然调度进来读,那不是很“逆天”了吗?

深入队列写入操作

写过程其实也是类似的!
在这里插入图片描述
因为遇到写满的情况下,写入数据是可以选择的等待的,想要等待你就乖乖休眠,把你的任务的TCB写入到Delay链表中,然后在队列链表中登记一下,到时候有位置写数据了第一时间叫你,你要是没有耐心等到的话就走吧。
成功写入了数据了,还要干什么吗?
成功写入到了数据了;那么队列就会有数据进入,可能在我没有写入进来之前可能有一个读任务想要读,但是由于没有数据可读休眠了,但是他很有耐心,选择了等待,那么他就会进入休眠状态,并且在List_t xTaskswaitingToReceive链表处登记了一下,那我成功了写入了数据有数据可读了,我就会去那个链表看看你是否还在那里,在的话就优先让你读走!
为什么要关闭中断呢?
一个工程中难免会有多个任务一起来写同一个队列,所以每次轮到谁来写了,肯定要吃独食啊,不然我写一半,你突然调度进来写,那不是很“人才”了吗?

读写队列出超时时间

读写任务休眠的时候,可以选择休眠,也是可以选择休眠多久的,不可能呆呆一直傻等着,所以等待的时候是可以设定等待时间的,时间一到,我就不等了被唤醒。
在这里插入图片描述

信号量

其实信号量就是特殊的队列,用的都是同样一套机制。
信号量就不像队列一样负责传递数据的,他更简单点,就负责“加减”一个计数值,这个计数值在创建的时候是可以自由设定的!
在这里插入图片描述
信号量和队列还有什么不同?
就是信号量的释放操作就等同于队列的写入操作,获取操作等同于读取操作!
信号量的释放操作是被设定没有等待时间的,要么释放成功,要么释放失败!

深入信号量获取以及释放操作

获取:
在这里插入图片描述
释放:
在这里插入图片描述
具体的操作和干了什么事情和队列大差不差,使用的同样的内部机制,了解了队列就相当于了解信号量!

互斥量

互斥量和信号量的不同

其实互斥量就是特殊的信号量,就是比信号量高级了一点,多了一个功能——优先级继承!互斥量依旧是维持一个“计数值”,但是互斥量的打这个计数值是不可以自由设定的,已经被设定死了为1,只能在0-1之间轮转!
那么优先级继承到底是个啥呢?
假设一个场景中使用了信号量:
由于低优先级的任务获取了信号量,使得最高优先级的任务卡住了(休眠),那么不就只能中优先级的任务运行了吗?(中优先级运行途中没有主动放弃CPU资源),那么低优先级的就不能及时释放信号量,就导致了最高优先级的任务一直被卡着!高优先级任务肯定很重要啊,不然怎么被设定为高优先级,所以重要的事一直没有去做,是很坏事的!
在这里插入图片描述
那换成使用互斥量,结果会怎么样呢?
在这里插入图片描述
显而易见,运行顺序显然不同了,在高优先级的任务被卡住后,低优先级任务居然可以在中优先级的任务前面先运行,太奇怪了,这就是互斥量的高级之处——优先级继承发挥了作用!
当一个任务因为使用互斥量被另一个任务卡住了,被迫休眠,那么内部就会比较一下这两个任务的优先级,假如,被卡住的任务的优先级>卡住别人的任务,那么卡住的任务就会将对方的优先级提高到像自己一样高级别的优先级,让他更早的运行,及时释放互斥量,让我(卡柱的任务)及时运行!在释放互斥量的一瞬间,那个卡住别人的任务就会自主的降低自己的优先级(恢复到到原来模样),所以说是自主降优先级的,不得不说那个卡住别人的任务还是有点识时务的!

深入源码看优先级继承是怎么操作到的

首先要很确切的理解是怎么操作的,要理解一下任务的运行以及调度机制,可以看一下我之前写的一篇文章:任务的内部机制
信号量中当一个任务去获取信号量的时候,失败了就会选择是否愿意等待,等待你就乖乖设定你的等待时间,然后 就去休眠吧,但是互斥量之所以高级,是因为他多做了一步——优先级继承,先去比较一下卡住你的任务和自己的优先级谁高谁低,然后再判断是否提升其优先级,这一步就是下面这一步:提高互斥量持有者的优先级!
在这里插入图片描述
那这句核心的代码里面到底做了什么呢?
经过了下面的这简单两步就得以提升了那个卡住别人的任务的优先级!
看不懂的可以看看这个文章:任务的内部机制
在这里插入图片描述
那提升了之后也是要恢复的呀,那是由谁来恢复呢?是有卡住别人的任务自己来降低的,释放互斥量一瞬间,就会自主降低自己的优先级!所以说那个恢复优先级的操作就隐藏在释放互斥量的函数里面:
在这里插入图片描述
里面有着这一句:(就是这个恢复了优先级)
在这里插入图片描述
那他里面到底做了什么操作呢?
原来里面的变量uxBasePriority记录了它原来的优先级,在这里插入图片描述
然后后面的操作不就是提升优先级的时候反过来而已嘛?
在这里插入图片描述
这样就实现了所谓的优先级继承

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

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

相关文章

如何打造高效办公楼物业管理系统?Java SpringBoot+Vue架构详解,实现智能化管理,提升工作效率

🍊作者:计算机毕设匠心工作室 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目…

GraphPad Prism 10 for Mac/Win:高效统计分析与精美绘图的科学利器

GraphPad Prism 10 是一款专为科研工作者设计的强大统计分析与绘图软件,无论是Mac还是Windows用户,都能享受到其带来的便捷与高效。该软件广泛应用于生物医学研究、实验设计和数据分析领域,以其直观的操作界面、丰富的统计方法和多样化的图表…

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据…

认知杂谈53

今天分享 有人说的一段争议性的话 I I 1.自助者天助 首先呢,咱得好好琢磨琢磨“自助者天助”这句话。这话说起来好像有点高深莫测的感觉,其实啊,道理特别简单。 就是说要是你自己都不乐意努力,那老天爷也不会平白无故地来帮你…

[环境配置]ubuntu20.04安装后wifi有图标但是搜不到热点解决方法

最近刚入手一台主机,暗影精灵8plus电竞主机,安装ubuntu后wifi怎么都搜不到热点,前后重装系统6次才算解决问题。这个心酸历程只有搞技术人才明白。下面介绍我解决过程。 首先主机到手后是个windows10系统,我用无线网连接了一下&am…

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(…

服务器流量监控工具vnStat的简单使用以及关于Linux的软中断信号(signal)的一点内容

一、服务器流量监控工具vnStat的简单使用 vnStat是为Linux和BSD设计的基于控制台的网络流量监控工具,通过它可以非常方便在命令行查看流量统计情况。它可以保留某个或多个所选择的网络接口的网络流量日志。为了生成日志,vnStat使用内核提供的信息。换句话…

2024年必看的4款录屏新星,谁才是你的菜?

嘿,小伙伴们,你们的职场好帮手来啦。今天我们要说说办公室里经常被忽略但实际上超有用的东西——录屏软件。现在大家都用数字化工具办公了,不管是做教学视频、记录会议,还是直播玩游戏,录屏软件都是必不可少的。可是市…

FRP内网穿透使用常见问题

本文解答一些关于FRP内网穿透的常见问题 FRP简介 FRP是一款开源的高性能反向代理应用,支持多种协议的内网穿透。它允许用户在外网环境中访问位于内网中的服务器和服务,如Web服务器、MySQL数据库、以及其他基于TCP/UDP的应用程序。FRP以其灵活的配置选项…

C++实现俄罗斯方块(Windows控制台版)

C实现俄罗斯方块(Windows控制台版) 在油管上看到一个使用C控制台编写的俄罗斯方块小游戏,源代码200多行,B站上也有相关的讲解视频,非常不错,值得学习。 B站讲解视频地址为:【百万好评】国外技术…

Unet改进27:添加DGCST|Vision Transformer与DGSM模块集成在一起的创新结构

本文内容:在不同位置添加DGCST 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 随着移动计算技术的快速发展,在移动设备上部署高效的目标检测算法成为计算机视觉的一个关键研究领域。本研究的重点是优化YOLOv7算法,以提高其在移动平台上的运行效率和速度…

【Linux】传输层协议——UDP

零、传输层的作用是负责数据能够从发送端传输到接收端 一、再来认识一下端口号 端口号(Port)标识了一个主机进行通信的不同的应用程序。在TCP/IP协议中,用“源IP”,“源端口号”,“目的IP”,“目的端口号”…

Request Response

1 前言 1.1 内容概要 理解Request、Response和HTTP报文之间的关系掌握通过Request能够获得的信息 请求URL、URI、请求协议请求头、客户机和主机请求参数 掌握通过Response能够完成的设置 响应中文乱码问题响应(Json)字符串、图片(文件&a…

【网络】UDP协议的简单使用

目录 服务器 客户端 测试 UDP是基于socket进行网络通信的,那我们这篇博客就来介绍一下基于UDP通信的基本流程,先让服务端和客户端进行简单的跨网络通信。 服务器 首先我们需要创建UDP套接字,用到的接口是 man socket 如果要使用UDP通信&am…

【Python知识宝库】面向对象编程:Python类的深度剖析

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、类的定义二、类的属性1. 类属性2. 实例属性 三、类的方法1. 实例方法2. 类方法 四、继承五、总结 前言 面向…

【C++ Primer Plus习题】12.3

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include "stock20.h&quo…

嵌入式OpenHarmony源码基本原理详解

大家好,今天主要给大家分享一下,如何分析与使用OpenHarmony源码,欢迎交流学习。 第一:OpenHarmony源码简介 在3.0版本中,Lite系统(即轻量系统和小型系统)、标准系统各有一套独立的构建入口和上层的构建流程,但在3.2版本中,两者开始互相借鉴,取长补短并实现了融合统一;…

【环境领域EI稳定 I 院士主讲】第九届能源与环境研究进展国际学术会议(ICAEER 2024)

ICAEER 2024会议投稿经过2-3位组委会专家严格审核之后&#xff0c;符合Springer ESE征稿要求的论文将由斯普林格&#xff08;Springer-Nature&#xff09;旗下的 Environmental Science and Engineering (ISSN: 1863-5520) 出版&#xff0c;出版后提交至EI Compendex&#xff…

初步了解VTK装配体

VTK还不太了解&#xff0c;根据资料&#xff0c; vtk.vtkAssembly 是 VTK库中的一个重要类&#xff0c;允许通过将多个vtkActor对象组合在一起来创建复杂的3D模型。 import vtk import math from vtk.util.colors import *filenames ["cylinder.stl","sphere…

C++11 --- 智能指针

序言 在使用 C / C 进行编程时&#xff0c;许多场景都需要我们在堆上申请空间&#xff0c;堆内存的申请和释放都需要我们自己进行手动管理。这就存在容易造成堆内存泄露&#xff08;忘记释放&#xff09;&#xff0c;二次释放&#xff0c;程序发生异常时内存泄露等问题&#xf…