当前位置: 首页 > news >正文

大白话解释---FreeRTOS中的队列集

1. 队列集是什么?

队列集(Queue Set) 就像 一个“多功能信箱”,可以同时监听 多个队列或信号量,并告诉你 哪个信箱里有新消息

  • 普通队列:只能单独检查一个队列是否有数据。

  • 队列集:可以同时监控多个队列/信号量,谁先来数据就处理谁


2. 为什么需要队列集?

假设你有以下任务:

  • 任务A:等待串口数据(队列1)。

  • 任务B:等待按键事件(队列2)。

  • 任务C:等待定时器信号(信号量)。

不用队列集的问题

  • 你需要轮流检查每个队列,效率低,还可能错过实时事件。

  • 比如:

    if (xQueueReceive(队列1, &data, 0) { ... }  // 查串口
    if (xQueueReceive(队列2, &data, 0) { ... }  // 查按键
    • 如果串口和按键同时来数据,可能漏掉按键。

用队列集

  • 一次监听所有队列,谁有数据就处理谁,不遗漏!


3. 队列集的本质
  • 是一个“监听器”:绑定多个队列/信号量,等待任意一个被触发。

  • 不存储数据:只通知你哪个队列有数据,仍需手动读取。

  • 解决多路阻塞问题:任务可以同时阻塞在多个队列上。


4. 使用步骤(以 FreeRTOS 为例)
(1)创建队列集
QueueSetHandle_t xQueueSet = xQueueCreateSet( 3 );  // 最多监听3个队列/信号量
(2)将队列/信号量加入队列集
xQueueAddToSet( xQueue1, xQueueSet );  // 把队列1加入监听
xQueueAddToSet( xQueue2, xQueueSet );  // 把队列2加入监听
xQueueAddToSet( xSemaphore, xQueueSet ); // 信号量也能监听
(3)等待事件并处理
// 阻塞等待任意一个队列/信号量触发
QueueSetMemberHandle_t xActivated = xQueueSelectFromSet( xQueueSet, portMAX_DELAY );if (xActivated == xQueue1) {xQueueReceive(xQueue1, &data, 0);  // 读队列1的数据printf("收到串口数据!\n");
} 
else if (xActivated == xQueue2) {xQueueReceive(xQueue2, &data, 0);  // 读队列2的数据printf("按键被按下!\n");
}
else if (xActivated == xSemaphore) {xSemaphoreTake(xSemaphore, 0);     // 取信号量printf("定时器到点了!\n");
}

5. 实际场景类比
  • 普通队列:像 单独的电话,你只能守着1个电话等消息。

  • 队列集:像 电话总机,多个分机(队列)接入,哪个响铃就接哪个。


6. 队列集 vs 单独轮询
方式队列集单独轮询队列
效率高(一次监听所有队列)低(需逐个检查)
实时性不遗漏事件可能延迟或遗漏
CPU占用低(阻塞等待)高(忙等待消耗CPU)
适用场景需要同时监听多个事件的任务简单场景(仅1-2个队列)

7. 注意事项
  1. 队列集本身不存储数据:它只是通知你该去哪个队列读数据。

  2. 队列和信号量需预先创建:不能动态加入/移除。

  3. 所有监听的队列必须为空:加入队列集前,确保队列没有残留数据。


总结

  1. 队列集的作用

    • 同时监听多个队列/信号量,解决“多路等待”问题。

  2. 核心优势

    • 避免轮询,提高效率,保证实时性。

  3. 适用场景

    • 需要处理 多个异步事件 的任务(如同时等待串口、按键、网络数据)。

一句话
队列集就是 FreeRTOS 的 “事件监听总机”,一个接口搞定所有队列和信号量的等待!

http://www.lryc.cn/news/605640.html

相关文章:

  • 基于知识驱动的解释性条件扩散模型用于无对比剂心肌梗死增强合成|文献速递-医学影像算法文献分享
  • CSS和XPATH选择器对比
  • 《Java 程序设计》第 15 章 - 事件处理与常用控件
  • Vibe Coding:AI驱动开发的安全暗礁与防护体系
  • 异步I/O和同步I/O
  • Day15--二叉树--222. 完全二叉树的节点个数,110. 平衡二叉树,257. 二叉树的所有路径,404. 左叶子之和
  • 在Linux中创建LVGL应用
  • Kotlin -> 普通Lambda vs 挂起Lambda
  • 【Django】-1- 开发项目搭建
  • Django模型迁移指南:从命令用法到最佳实践
  • HttpServletRequest详细解释
  • 如何在NPM上发布自己的React组件(包)
  • 人工智能概念之十一:常见的激活函数与参数初始化
  • Cesium 快速入门(四)相机控制完全指南
  • langchain--1--prompt、output格式、LCEL示例
  • 【烧脑算法】Dijkstra 算法:解决最短路问题
  • 会议室预定系统核心技术:如何用一行SQL解决时间冲突检测难题
  • LLC电源原边MOS管DS增加RC吸收对ZVS的影响分析
  • ode with me是idea中用来干嘛的插件
  • 山东移动云主机:技术架构与特性解析
  • AI 安监系统:为工业园安全保驾护航
  • 1 机器学习概述 (第一天2025.7.31)
  • RabbitMQ 队列配置设置 RabbitMQ 消息监听器的并发消费者数量java
  • Java 大视界 -- Java 大数据在智能医疗远程健康监测与疾病预防预警中的应用(374)
  • Linux 进程管理与计划任务
  • linux git ssh配置过程
  • React中的this绑定
  • SpringMVC的核心架构与请求处理流程
  • PostgreSQL dblink 与 Spring Boot @Transactional 的事务整合
  • 网络层概述