队列 的初识

news2024/10/9 0:51:32

Q: 什么是队列?

A: 队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息。                 

Q: 为什么不使用全局变量?

A: 如果使用全局变量,任务1修改了变量 a ,等待任务3处理,但任务3处理速度很慢,在处理数据的过程中,任务2有可能又修改了变量 a ,导致任务3有可能得到的不是正确的数据。

在这种情况下,就可以使用队列。任务1和任务2产生的数据放在流水线上,任务3可以慢慢一个个依次处理。

名词认识:

  • 队列项目:队列中的每一个数据;
  • 队列长度:队列能够存储队列项目的最大数量;

创建队列时,需要指定队列长度及队列项目大小

队列特点

数据入队出队方式

通常采用先进先出(FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取。 也可以配置为后进先出(LIFO)方式,但用得比较少。

数据传递方式

采用实际值传递,即将数据拷贝到队列中进行传递,也可以传递指针,在传递较大的数据的时候 采用指针传递。

多任务访问

队列不属于某个任务,任何任务和中断都可以向队列发送/读取消息

出队、入队阻塞

当任务向一个队列发送消息时,可以指定一个阻塞时间假设此时队列已满无法入队, 阻塞时间就是等待入队的时间。

阻塞时间如果设置为:

  • 0:直接返回不会等待
  • (0,port_MAX_DELAY):等待设定的阻塞时间,若在该时间内还无法入队,超时后直接返回不 再等待
  • port_MAX_DELAY:死等,一直等到可以入队为止。出队阻塞与入队阻塞类似

队列相关 API 函数

创建队列(动态)

  • uxQueueLength:队列可同时容纳的最大项目数 。
  • uxItemSize:存储队列中的每个数据项所需的大小(以字节为单位)。
  • 返回值: 如果队列创建成功,则返回所创建队列的句柄 。 如果创建队列所需的内存无法分配 ,则返回 NULL。 

写队列

 

  • xQueue:队列的句柄,数据项将发送到此队列。
  • pvItemToQueue:待写入数据
  • xTicksToWait:阻塞超时时间
  • 返回值: 如果成功写入数据,返回 pdTRUE,否则返回 errQUEUE_FULL。

读队列

  • xQueue:待读取的队列
  • pvItemToQueue:数据读取缓冲区
  • xTicksToWait:阻塞超时时间
  • 返回值: 成功返回 pdTRUE,否则返回 pdFALSE

实操演示

需求: 创建一个队列,按下KEY1向队列发送数据,按下KEY2向队列读取数据。

在 C:\mjm_CubeMX_proj 路径下,复制一份Cube的母版并重命名为 :mjm_freeRTOS_queue:

打开相应的Cube文件:

1. 先设置两个按键的GPIO口:

2. 找到左侧的Middleware --> FREERTOS,然后在下方找到"Task and Queues": 

2.1 创建两个任务:

2.2 创建一个队列: 

 

 上图代表,队列长度16每个数据大小16个bit(双字节)

3. 在Keil中

3.1 打开freertos.c,可以看到Cube生成的 生成队列和任务的代码

同样的,上图中的 osMessageCreate() 函数也是Cube对于 xQueueCreate() 函数的封装。

3.2  代码编写:

freertos.c中:

#include "stdio.h"

void StartTask_send(void const * argument)
{
	uint16_t buf = 100; //要写入队列的值
	BaseType_t status;
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){
			osDelay(20);
			if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){ //按键消抖
				printf("KEY1 has been pressed\r\n");
				status = xQueueSend(myQueueHandle, &buf, 0); //Cube没有封装这个函数,直接调用“写队列”的函数
				if(status == pdTRUE){ //说明写入成功
					printf("data \"%d\" has been successfully written into queue\r\n",buf);
				}else{ //说明写入失败
					printf("fail to write data into queue\r\n");
				}			
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET); //等待按键松开,防止出现按钮一直按着,就一直删除创建任务			
		}
		osDelay(10);

  }
}


void StartTask_receive(void const * argument)
{
	uint16_t buf; //用来接收数据的变量
	BaseType_t status;
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){
			osDelay(20);
			if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){ //按键消抖
				printf("KEY2 has been pressed\r\n");
				status = xQueueReceive(myQueueHandle, &buf, 0); //Cube没有封装这个函数,直接调用“读队列”的函数
				if(status == pdTRUE){ //说明读取成功
					printf("data\"%d\"has been read and deleted\r\n",buf);
				}else{ //说明读取失败
					printf("fail to read data from queue\r\n");
				}			
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET); //等待按键松开,防止出现按钮一直按着,就一直删除创建任务			
		}
		osDelay(10);
  }
}

实现效果

打开串口助手,按一下KEY1:

再按一下KEY2:

 

此时队列已经没有数据了,所以如果再按一下KEY2:

如果此时再按17下KEY1:

第17下就无法写入了,因为队列长度为16

那么显然,如果此时再按17下KEY2:

只能读取16次,17次就没有数据可读可删了!

 

 

 

 

 

 

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

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

相关文章

IIC外设通信

文章目录 IIC外设简介功能介绍框图简化结构图主机发送流程主机接收流程 IIC外设简介 STM32内部集成了硬件IIC收发电路,可由硬件自动执行时钟生成,起始终止条件生成,应答收发位,数据收发等功能,减轻CPU负担。 功能介绍…

2023年深圳杯数学建模D题基于机理的致伤工具推断

2023年深圳杯数学建模 D题 基于机理的致伤工具推断 原题再现: 致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同,相同的致伤工具在人体组织上会形成不同的损伤形态,不同的致伤工具也可能形成相同的损伤形态。致伤…

Kubernetes ConfigMap - Secret - 使用ConfigMap来配置 Redis

目录 ConfigMap : 参考文档:k8s -- ConfigMap - 简书 (jianshu.com) K8S ConfigMap使用 - 知乎 (zhihu.com) ConfigMap的作用类型: 可以作为卷的数据来源:使用 ConfigMap 来配置 Redis | Kubernetes 可以基于文件创建 Conf…

【C++】类和对象-封装

1.属性和行为作为整体 2.示例2-设计学生类 3.访问权限 4.class和struct的区别 5.成员属性设置为私有 6.设计案例1-立方体类 在main函数前重新补上isSame函数 在Cube类里面添加issamebyclass,利用成员函数判断两个立方体是否相等 自己写的代码: #in…

开放式耳机怎么选?值得入手的开放式耳机有哪些

与封闭式耳机相比,开放式耳机具有更为自然、真实的音质,能够更好地还原音乐现场的声音环境。以下是几款值得推荐的开放式耳机,都来看看有哪些吧。 Top1、NANK南卡00压开放式耳机 推荐理由:死磕开放式传音技术,音质和…

(十四)InfluxDB仪表盘

以下内容来自 尚硅谷,写这一系列的文章,主要是为了方便后续自己的查看,不用带着个PDF找来找去的,太麻烦! 第 14 章 InfluxDB仪表盘 14.1 什么是InfluxDB仪表盘 1、前面已经给大家介绍过InfluxDB的仪表盘功能了。点击…

免费数据恢复方法?这3个不要错过!

朋友们!本人是个超级马虎的职场新手,在处理工作的时候总是容易误删重要的报表!要知道我光是做一个报表就要花很长时间。大家有什么免费数据恢复的方法给我推荐推荐吗?感谢!” 在使用电脑时,我们会在电脑中保…

性能测试工具 Jmeter 引入 jar 包踩过的坑

目录 前言: Jmeter 中调用自己编写 jar 中的类出错 错误日志: 出现以上错误的原因: 解决方法: 前言: JMeter 是一种开源的性能测试工具,可以帮助我们快速地进行网站、应用程序等的性能测试和压力测试…

SSM企业固定资产智能管理系统的设计与实现【纯干货分享,M免费领取源码06298】

摘要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对企业固定资产智能管理系统等问题&#xff0c…

计算机系统结构-多处理机

概念,多处理机指的是,多台含cpu的机器共享一个存储器。 (可以通过网络宽带,也可以通过线直连这个存储器。当然他们也可以有自己的私有存储器或者高速缓存) 几个cpu公用一个总线,没问题。但是如果十几个cpu…

系统学习Linux-MySQL语句(二)

一、SQL语句类型 DDLDDL(Data Definition Language,数据定义语言):用于定义数据库中的各种对象,包括数据库、表、视图、触发器等,常见的 DDL 命令有 CREATE、ALTER、DROPDMLDML(Data Manipulat…

YOLOv1论文细节总结(confidence)

总结几个细节点: 1、置信度计算: 训练时: 测试时置信度,这里网络输出仍然是 以上是各大博文讲解时列出的也是论文中提到的公式,但其实最清楚的是下面这段文字讲出的: 说白了: 网络输出三个…

深圳国际新能源及智能网联汽车全产业博览会今年10月举办

7月25日,深圳市工业和信息化局与励展博览集团共同在深圳举办Automotive World China 2023深圳国际新能源及智能网联汽车全产业博览会(简称“AWC 2023”)全球推介启动大会,该博览会将于2023年10月11日-13日在深圳国际会展中心盛大举…

K8S初级入门系列之十-控制器(StatefulSet)

一、前言 在前面的系列K8S初级入门系列之六-控制器(RC/RS/Deployment),K8S初级入门系列之七-控制器(Job/CronJob/Daemonset)我们已经介绍了多种控制器,今天我们将介绍最后一种控制器--StatefulSet,顾名思义,即有状态Set&#xff0…

我的第一个flutter项目(Android Webview)

前言:flutter开发环境搭建Flutter的开发环境搭建-图解_☆七年的博客-CSDN博客 第一个flutter简单项目,内容是一个主界面,其中: 1.内容点击数字自增 2.跳转一个空页, 3.跳转一个WebView界面 其中涉及添加主键&#xf…

选择合适明星代言:确保品牌传播与销售成功的关键一步

在当今激烈的市场竞争中,企业需要不断探索新的营销策略来吸引消费者的关注和忠诚度。其中一种被广泛采用的方法是邀请明星代言产品或品牌。判断想请的明星与自己的产品是否相合适是十分重要的步骤,这关系到代言活动的成功与否。以下是一些方法可以帮助你…

DuckDB全面挑战SQLite

概要 当我们想要在具有嵌入式数据库的本地环境中工作时,我们倾向于默认使用 SQLite。虽然大多数情况下这都很好,但这就像骑自行车去 100 公里之外:可能不是最好的选择。 这篇文章中将讨论以下要点: • DuckDB 简介:它…

企业邮箱默认发信账户用途说明及设置方法

有的时候,企业有多个子公司,或者对内和对外需要用不同的邮箱地址,或者发给不同的人需要用不同的邮箱地址,这个时候企业或用户一般会设置别名邮箱用来区分。 那么问题来了,这么多邮箱账号,我发信的时候默认…

大模型的淘金时代,HPE给出了一份智能经济“奇点”攻略

进入2023年,ChatGPT引发了一个新的AI时代——大模型时代。陆奇说:“我已经跟不上大模型时代的狂飙速度了!”大模型引发了AI产业整体升级换代,各种大模型层出不穷,科技公司纷纷入局,AI创业公司再次雨后春笋般…

【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)

探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析) Redis提供的持久化机制Redis持久化如何工作Redis持久化的故障分析持久化频率操作分析数据库多久调用一次write,将数据写入内核缓冲区?内核多久将系统缓冲…