FreeRTOS信号量

信号量简介

              def 1: 信号量是一种解决问题的机制,可以实现共享资源的访问

信号量浅显理解例子:

空车位: 信号量资源(计数值)

让出占用车位: 释放信号量(计数值++)

占用车位:获取信号量(计数值--)

当计数值大于0时,代表信号量有资源,当释放信号量,信号量计数值(资源数) + 1

当获取信号量,信号量计数值(资源数) - 1,信号量处于传递状态

信号量的计数值都是有限制的:限定最大值,如果最大值被限定为1,那么它就是二值信号量,如果最大值不是1,它就是计数型信号量。

def 2 :队列和信号量之间的对比

注:

队列

         1: 队列可以容纳多个数据,创建队列有两部分内存,队列结构体+队列项存储空间

         2: 写入队列:当队列满时,可以阻塞

         3: 读取队列: 当队列空时,可以阻塞

信号量

        1:仅存放计数值,无法存放其他数据,创建信号量,只需分配信号量结构体

        2:释放信号量:不可阻塞,计数值++,当计数值为最大值时,返回失败

        3:获取信号量:计数值-- ,当没有资源时,可以阻塞

注:

       计数值代表的是当前信号量的资源数


信号量这个名字很恰当:

  • 信号:起通知作用

  • 量:还可以用来表示资源的数量

  • 当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)

  • 当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)

  • 支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1

计数型信号量的典型场景是:

  • 计数:事件产生时"give"信号量,让计数值加1;处理事件时要先"take"信号量,就是获得信号量,让计数值减1。

  • 资源管理:要想访问资源需要先"take"信号量,让计数值减1;用完资源后"give"信号量,让计数值加1。

信号量的"give"、"take"双方并不需要相同,可以用于生产者-消费者场合:

  • 生产者为任务A、B,消费者为任务C、D

  • 一开始信号量的计数值为0,如果任务C、D想获得信号量,会有两种结果: 阻塞:买不到东西咱就等等吧,可以定个闹钟(超时时间) 即刻返回失败:不等

  • 任务A、B可以生产资源,就是让信号量的计数值增加1,并且把等待这个资源的顾客唤醒

唤醒谁?谁优先级高就唤醒谁,如果大家优先级一样就唤醒等待时间最长的人

二值信号量简介 :

def:二值信号量本质是一个长度为1的队列,该队列只有空和满两种状态,这就是二值,当队列处于满状态时值为1,当队列处于空状态时值为0。

二值信号量通常用于互斥访问和任务同步,与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转问题,所以二值信号量更适合同步,

同步和互斥概念:

【互斥】

互斥是指在计算机科学领域中的一种同步机制,用于确保在同一时间只有一个进程或线程能够访问某个共享资源,防止因多个进程同时访问而导致数据混乱或错误的情况发生。当一个进程正在访问共享资源时,其他进程必须等待该进程释放资源后才能访问,从而确保资源的独占性。互斥的目的是保护共享资源的完整性和一致性,避免竞争条件的发生,保证程序的正确性和稳定性。Mutex(互斥锁)是实现互斥的一种常见机制。

【同步】

同步是指在计算机编程中一种协调多个线程或进程之间操作的机制。通过同步机制,可以确保多个线程或进程在执行过程中按照一定顺序或规则进行交互,以避免数据竞争、死锁等问题的发生。同步可以实现数据的共享和通信,确保数据的一致性和正确性。常见的同步机制包括互斥锁、信号量、事件等,通过这些机制,可以控制线程或进程的执行顺序、访问共享资源的次序,以及协调它们之间的操作。同步是实现多任务协同工作的重要手段,保证了程序的正确性和稳定性。


二值信号量API函数(熟悉

使用二值信号量的过程: 创建二值信号量 ---> 释放二值信号量 ---> 获取二值信号量

创建:

  • 使用信号量之前,要先创建,得到一个句柄;使用信号量时,要使用句柄来表明使用哪个信号量。

  • 对于二进制信号量、计数型信号量,它们的创建函数不一样:

  • 释放信号量 (任务级) -----------> xSemaphorGive()

  • 在中断中释放信号量(中断级) -------------> xSemaphorGiveFromISR()

  • 获取信号量(任务级) ----------------------> xSemaphoreTask()

  • 在中断中获取信号量(中断级) ---------------> xSemaphoreFromISR()

创建二进制信号量的函数原型如下:

/* 创建一个二进制信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateBinary( void );
/* 创建一个二进制信号量,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个StaticSemaphore_t结构体,并传入它的指针
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t
*pxSemaphoreBuffer );

创建计数型信号量的函数原型如下:

/* 创建一个计数型信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* uxMaxCount: 最大计数值
* uxInitialCount: 初始计数值
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t
uxInitialCount);
/* 创建一个计数型信号量,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个StaticSemaphore_t结构体,并传入它的指针
* uxMaxCount: 最大计数值
* uxInitialCount: 初始计数值
* pxSemaphoreBuffer: StaticSemaphore_t结构体指针
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount,
StaticSemaphore_t
*pxSemaphoreBuffer );

释放二值信号量的函数:

------------------------------------------------------正点原子-----------------------------------------------

描述:(返回值描述)


-------------------------------------韦东山老师-------------------------------------------------------------

删除:

  • 对于动态创建的信号量,不再需要它们时,可以删除它们以回收内存。

  • vSemaphoreDelete可以用来删除二进制信号量、计数型信号量,函数原型如下:

/*
* xSemaphore: 信号量句柄,你要删除哪个信号量
*/
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

give/take

二进制信号量、计数型信号量的give、take操作函数是一样的。这些函数也分为2个版本:给任务使 用,给ISR使用。列表如下:

xSemaphoreGive的函数原型如下:【释放二值信号量

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

pxHigherPriorityTaskWoken的函数原型如下:

BaseType_t xSemaphoreGiveFromISR(
        SemaphoreHandle_t xSemaphore,
        BaseType_t *pxHigherPriorityTaskWoken
);	

xSemaphoreGiveFromISR函数的参数与返回值列表如下:

xSemaphoreTake的函数原型如下:【获取二值信号量


--------------------------正点原子---------------------------------------------------------------------------

------------------------------韦东山老师--------------------------------------------------------------------

BaseType_t xSemaphoreTake(
            SemaphoreHandle_t xSemaphore,
            TickType_t xTicksToWait
);

xSemaphoreTakeFromISR的函数原型如下:

BaseType_t xSemaphoreTakeFromISR(
           SemaphoreHandle_t xSemaphore,
           BaseType_t *pxHigherPriorityTaskWoken
);

xSemaphoreTakeFromISR函数的参数与返回值列表如下:

两种信号量之间的对比

信号量的计数值都有限制:限定了最大值。如果最大值被限定为1,那么它就是二进制信号量;如果最 大值不是1,它就是计数型信号量。

差别列表如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LT6911UXB HDMI2.0 至四端口 MIPI DSI/CSI,带音频 龙迅方案

1. 描述LT6911UXB 是一款高性能 HDMI2.0 至 MIPI DSI/CSI 转换器,适用于 VR、智能手机和显示应用。HDMI2.0 输入支持高达 6Gbps 的数据速率,可为4k60Hz视频提供足够的带宽。此外,数据解密还支持 HDCP2.2。对于 MIPI DSI / CSI 输出&#xff0…

jvm 马士兵 01

01.JVM是什么 JVM是一个跨平台的标准 JVM只识别class文件,符合JVM规范的class文件都可以被识别

知乎广告开户流程,知乎广告的优势是什么?

社交媒体平台不仅是用户获取知识、分享见解的场所,更是品牌展示、产品推广的重要舞台。知乎作为国内知名的知识分享社区,以其高质量的内容生态和庞大的用户基础,成为了众多企业进行广告投放的优选之地。云衔科技通过其专业服务,助…

数字身份管理:Facebook如何利用区块链技术?

随着数字化进程的加速,个人身份管理已成为一个关键议题。在这方面,区块链技术正在逐渐展现其巨大潜力。作为全球最大的社交媒体平台,Facebook也在积极探索和应用区块链技术来改进其数字身份管理系统。本文将深入探讨Facebook如何利用区块链技…

<Linux> 权限

目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组 权限 权限是操作系统用来限制对资源访问的机制,权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组,通过这样的机制来限制哪些用户、哪些组可以对特定文件…

Node私库Verdaccio使用记录,包的构建,推送和拉取

Node私库Verdaccio使用记录,包的构建,推送和拉取 Verdaccio是一个轻量级的私有npm代理注册中心,它可以帮助你在本地搭建一个npm仓库,非常适合企业内部使用。通过使用Verdaccio,你可以控制和缓存依赖包,提高…

政安晨:【Keras机器学习示例演绎】(二十七)—— 利用 NNCLR 进行自我监督对比学习

目录 简介 自我监督学习 对比学习 NNCLR 设置 超参数 加载数据集 增强 准备扩增模块 编码器结构 用于对比预训练的 NNCLR 模型 预训练 NNCLR 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望…

DRF限流组件源码分析

DRF限流组件源码分析 开发过程中,如果某个接口不想让用户访问过于频繁,可以使用限流的机制 限流,限制用户访问频率,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷。 对于…

Spring - 7 ( 13000 字 Spring 入门级教程 )

一:Spring Boot 日志 1.1 日志概述 日志对我们来说并不陌生,我们可以通过打印日志来发现和定位问题, 或者根据日志来分析程序的运行过程,但随着项目的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题 比如有时需要…

【LDAP】LDAP 和 AD 介绍及使用 LDAP 操作 AD 域

LDAP 和 AD 介绍及使用 LDAP 操作 AD 域 1.LDAP入门1.1 定义1.2 目录结构1.3 命名格式 2.AD 入门2.1 AD 定义2.2 作用2.3 AD 域结构常用对象2.3.1 域(Domain)2.3.2 组织单位(Organization Unit)2.3.3 群组(Group&#…

服务器数据恢复—多块磁盘离线导致阵列瘫痪,上层lun不可用的数据恢复案例

服务器存储数据恢复环境: 某品牌MSA2000存储,该存储中有一组由8块SAS硬盘(其中有一块热备盘)组建的RAID5阵列,raid5阵列上层划分了6个lun,均分配给HP-Unix小型机使用,主要数据为oracle数据库和O…

Mac 上安装多版本的 JDK 且实现 自由切换

背景 当前电脑上已经安装了 jdk8; 现在再安装 jdk17。 期望 完成 jdk17 的安装,并且完成 环境变量 的配置,实现自由切换。 前置补充知识 jdk 的安装路径 可以通过查看以下目录中的内容,确认当前已经安装的 jdk 版本。 cd /Library/Java/Java…

解决WordPress无法强制转换https问题

原因:我在用cs的时候,突然老鸟校园网突然断了,客户端cs连不上了,进程也杀不死,cpu占用100%,只能重启,但是重启后我的blog网站打不开了 开始以为是Nginx的问题,重启它说配置出了问题…

基于Springboot的在线博客网站

基于SpringbootVue的在线博客网站的设计与实现 开发语言:Java数据库:MySQL技术:SpringbootMybatis工具:IDEA、Maven、Navicat 系统展示 用户登录 首页 博客标签 博客分类 博客列表 图库相册 后台登录 后台首页 用户管理 博客标…

Word文件导出为PDF

Word文件导出为PDF 方法一、使用Word自带另存为PDF功能 打开需要转换为PDF格式的Word文件,依次点击【文件】➡【另存为】➡选择文件保存类型为.PDF 使用这种方法导出的PDF可能存在Word中书签丢失的情况,在导出界面点击,选项进入详细设置 勾…

算法系列--BFS解决拓扑排序

💕"请努力活下去"💕 作者:Lvzi 文章主要内容:算法系列–算法系列–BFS解决拓扑排序 大家好,今天为大家带来的是算法系列--BFS解决拓扑排序 前言:什么是拓扑排序 拓扑排序–解决有顺序的排序问题(要做事情的先后顺序) …

Vulntarget-a 打靶练习

关于环境配置,这里就不在附上图片和说明了,网上一大堆,这里只针对自己练习,做一个记录。 外网信息收集 利用arpscan工具,扫描了当前局域网中都存在哪些主机: 正常来说我们不应该使用arpscan,而是…

各个硬件的工作原理

目录 前言 主存储器的基本组成 运算器的基本组成 控制器的基本组成 计算机的工作过程 前言 上个小节我们学习了现代计算机的基本构成都是基于冯诺依曼的思想来设计的,那么本章节要来看看主机内部三个组件的细节以及它们之间相互协调工作的. 主存储器的基本组成 这张图非常…

WPF基础应用

WPF参考原文 MVVM介绍 1.常用布局控件 1.1 布局控件 WPF(Windows Presentation Foundation)提供了多种布局容器来帮助开发者设计用户界面,以下是一些常用的布局: Grid: Grid是最常用的布局容器之一,它允许你通过定…

暗区突围端游海外版|暗区突围怎么玩 新手游玩攻略分享

游戏中健康系统与其它射击游戏有很大区别,根据受伤部位、伤势的不同,会有不同的表现。除了头部之外,其它部位如果损坏后继续受到伤害,那么伤害将会分摊到身体其它部位。在暗区内或者暗区外都可以对角色进行治疗,角色不…