天耀中华 发表于 2023-12-26 23:43:22

RT_thread系统下通过消息队列传输数组实现线程间通信

对于一个数据采集线程,和一个数据接收线程而言。消息队列相较于邮箱能够传输不定长字节的数据。
但是,对于数据采集线程,有时需要持续性采集多次的数据,每次都放进数组中,然后将他们一次性全部发送出去,这个时候就是需要注意
区分,我们到底是每次采完直接发送,,达到指定数据后才提醒接收线程接收。
还是将数据放在数组中,将数组一次性发出。
举个简单的例子,比如,线程1需要采集50个数据为1组发送给线程2
此时,线程1每接收一个发送一个,然后线程2统一接收。

#include <rtthread.h>

#define ARRAY_SIZE 50

static rt_mq_t mq;
static rt_sem_t sem;
static float data;

static void producer_thread_entry(void *parameter)
{
    float temp_data;
    for (int i = 0; i < 50; i++)
    {
      // 采集数据
      temp_data = ...;// 采集数据的逻辑
      // 发送数据到消息队列
      rt_mq_send(mq, &temp_data, sizeof(float));
      // 判断是否采集了50次数据
      if (i == 49)
      {
            // 发送信号量给消费者线程
            rt_sem_release(sem);
      }
      rt_thread_mdelay(1000);// 延时 1 秒
    }
}

static void consumer_thread_entry(void *parameter)
{
    float received_data;
    while (1)
    {
      // 等待信号量
      rt_sem_take(sem, RT_WAITING_FOREVER);
      // 接收数据从消息队列
      for (int i = 0; i < ARRAY_SIZE; i++)
      {
            rt_mq_recv(mq, &received_data, sizeof(float), RT_WAITING_FOREVER);
      }
      // 处理接收到的数据
      for (int i = 0; i < ARRAY_SIZE; i++)
      {
            // 处理 received_data
      }
    }
}

int main(void)
{
    mq = rt_mq_create("mq", sizeof(float), 50, RT_IPC_FLAG_FIFO);
    if (mq == RT_NULL)
    {
      rt_kprintf("Failed to create message queue\n");
      return -1;
    }

    sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
    if (sem == RT_NULL)
    {
      rt_kprintf("Failed to create semaphore\n");
      return -1;
    }
    rt_thread_t tid1 = rt_thread_create("producer", producer_thread_entry, RT_NULL, 1024, 10, 10);
    if (tid1 != RT_NULL)
    {
      rt_thread_startup(tid1);
    }
    rt_thread_t tid2 = rt_thread_create("consumer", consumer_thread_entry, RT_NULL, 1024, 20, 10);
    if (tid2 != RT_NULL)
    {
      rt_thread_startup(tid2);
    }
    while (1)
    {
      rt_thread_mdelay(1000);
    }
}

这个时候,创建消息队列的时候,就是
mq = rt_mq_create("mq", sizeof(float),//每个消息的最大字节数
                                     , 50                //消息队列中最多有多少消息
                                     ,RT_IPC_FLAG_FIFO);

当我们将50个数据封装程一个数组,然后将数组一次性通过消息队列发送给线程2的时候
例如 定义数组 float   value_data; 存放数据
这个时候,创建的消息队列应该是

mq = rt_mq_create("mq", sizeof(float)*50,//每个消息(这里的每个消息就是指的这个数组是一个消息)的最大字节数
                                     , 3            //消息队列中最多有多少消息,(随便设定,实测,不易过大)
                                     ,RT_IPC_FLAG_FIFO);

这个特别注意,在创建消息队列,传输数组的时候,数组作为消息发送的时候,单个消息的大小=sizeof(数组的存储类型float)*数组深度
页: [1]
查看完整版本: RT_thread系统下通过消息队列传输数组实现线程间通信