硬汉嵌入式论坛

 找回密码
 立即注册
查看: 400|回复: 0
收起左侧

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

[复制链接]

7

主题

4

回帖

25

积分

新手上路

积分
25
发表于 2023-12-26 23:43:22 | 显示全部楼层 |阅读模式
对于一个数据采集线程,和一个数据接收线程而言。消息队列相较于邮箱能够传输不定长字节的数据。
但是,对于数据采集线程,有时需要持续性采集多次的数据,每次都放进数组中,然后将他们一次性全部发送出去,这个时候就是需要注意
区分,我们到底是每次采完直接发送,,达到指定数据后才提醒接收线程接收。
还是将数据放在数组中,将数组一次性发出。
举个简单的例子,比如,线程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[ARRAY_SIZE];

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[ARRAY_SIZE];
    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[50]; 存放数据
这个时候,创建的消息队列应该是

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

这个特别注意,在创建消息队列,传输数组的时候,数组作为消息发送的时候,单个消息的大小=sizeof(数组的存储类型float)*数组深度
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 22:49 , Processed in 0.145279 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表