• 使用消息队列 queue 实现数据通信


    使用消息队列 queue 实现数据通信

    概述

    如前所述:使用全局变量传递数据的方式存在一些限制,如读写时的数据保护与同步问题、数据缓存的问题(新数据会覆盖旧数据)。

    使用队列则可以自动解决上述问题。队列在实现上已经添加了一定的读写保护、并具备一定的存储长度,来缓存一定的数据。当发送数据的一方速度快于使用数据的一方,或者多个数据发送方的情况下,这种缓存机制可以缓解使用数据的一方的一定的处理压力。

    此外,队列实现的延时发送机制(发送失败的情况下,若延时时间不为0,可以等待一段时间再发送数据)也可以改善通信双方的速率差异。

    xQueueSend(xQueue, // 要发送数据的队列
    pvItemToQueue,     // 要发送到队列的条目(item)
    xTicksToWait)      // 队列满时,延时等待的时间
    
    • 1
    • 2
    • 3

    用邮箱实现多事件的单向同步章节中,已经介绍了队列的基本使用方法和注意事项,这里仅从数据通信的角度给出一些示例。

    需求及功能解析

    队列适合每次传输的数据长度固定的情况,并且可以应用在数据传输中有多个发送方、多个接收方的的场景。

    实际的项目中,产生数据的一方可能多次生产数据,然后将数据发送到另一个任务进行处理。比如,数据采集设备中会多次采集数据,然后将数据发送到另一个任务进行计算、显示到屏幕上等。

    示例给出了这样的示例:任务1每生产五个数据,就通过队列发送到任务2。

    示例解析

    示例输出:

    This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295348 bytes
    TASK2: The buffer data is as follows:00 00 00 00 00 
    
    TASK2: The buffer data is as follows:00 01 02 03 04 
    
    TASK2: The buffer data is as follows:05 06 07 08 09 
    
    TASK2: The buffer data is as follows:0a 0b 0c 0d 0e 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    讨论

    对多次产生数据,集中处理一次的应用场景,使用队列时,存在以下的限制:

    1)队列要求每次产生的条目的长度是一样的,如示例中创建的队列的元素类型为 int array[5],则每次最大发送5个数据,超过5个数据的情况下,无法使用该队列进行传输。

    2)多次采集单次触发发送的机制需要自己在应用层进行实现。示例中发送方任务1通过计数,来控制这种逻辑:

    if(remainder == 0) {
         if (xQueueSendToFront(custom_queue, (void *)&data_send, 0) != pdTRUE) { // 每五次发送一个数据
               printf("%s: failed send\n", TASK1_TAG); // 检查是否发送失败
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在后续的学习中,我们将介绍具备发送不固定长度的数据、满足一定数量后自动触发接收的通信组件,它们是队列相关特性的补充。

    总结

    1)队列兼具数据传输,同步的两种功能。

    2)队列适合每次传输的数据长度固定的情况,并且可以应用在数据传输中有多个发送方、多个接收方的的场景。

    3)队列的不足之处是要求每次发送的条目的长度是一样的,并且没有实现自动完成多次发送触发单次接收的机制。

    4)大部分情况下,复杂的数控类型,队列传递的往往是指针类型。

    资源链接

    1)Learning-FreeRTOS-with-esp32 系列博客介绍
    2)对应示例的 code 链接 (点击直达代码仓库)

    3)下一篇:使用 stream buffer 传递数据

  • 相关阅读:
    VMware16安装RedHat7.6步骤
    防止砍单、封号:亚马逊、沃尔玛测评方案优化建议
    第七章第二节:B树和B+树
    面试官:什么是Java内存模型?
    [思维]Color the Picture Codeforces1711C
    一文搞懂系列之SpringMVC开发步骤及项目框架注册
    多线程高频考点(如何解决死锁,谈谈HashMap HashTable ConcurrentHashMap的区别)
    YoloV8改进策略:Inner-IoU+clou,YoloV8的涨点明珠
    linux下如何hook第三方播放器的视频数据?
    LeetCode二叉树系列——144.二叉树的最小深度
  • 原文地址:https://blog.csdn.net/wangyx1234/article/details/127659642