线程间通信之消息队列

1. 示例代码

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-02-07     冷月枫       the first version
 */
/* 初始化2个静态线程 ,一个线程会从消息队列中读取消息,
 * 另一个线程会定时给消息队列发送普通信息和紧急信息*/

#include <rtthread.h>

/* 消息队列控制块 */
static struct rt_messagequeue mq;
/* 消息队列中用到的放置消息的内存池 */
static rt_uint8_t msg_pool[2048];

ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;

/* 线程1入口函数 */
static void thread1_entry(void* parameter)
{
    char buf = 0;
    rt_uint8_t cnt = 0;

    while(1)
    {
        /* 从消息队列中接收消息 */
        if(rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
        {
            rt_kprintf("thread1 recv from msg queue, the content is %c\n",buf);
            if(cnt == 19)
            {
                break;

            }
        }

        cnt ++;
        rt_thread_mdelay(50);
    }
    /* 脱离队列 */
    rt_kprintf("thread1 detach! \n");
    rt_mq_detach(&mq);
}
/* 线程2入口函数 */
static void thread2_entry(void* parameter)
{
   int re;
   char buf = 'A';
   rt_uint8_t cnt = 0;

   while(1)
   {
       if(cnt == 8)
       {
           /* 发送紧急消息到消息队列中 */
           re = rt_mq_urgent(&mq, &buf, sizeof(buf));
           if(re != RT_EOK)
           {
               rt_kprintf("rt_mq_urget failed!\n");
           }else {
            rt_kprintf("thread2 send urgent message: %c\n",buf);
           }
       }else if(cnt >= 20)
       {
           rt_kprintf("message queue stop send, thread2 quit'n");
            break;
       }else {
        /* 发送普通消息到消息队列 */
           re = rt_mq_send(&mq, &buf, sizeof(buf));
           if(re != RT_EOK)
           {
               rt_kprintf("rt_mq_send failed!\n");
           }else {
            rt_kprintf("thread2 send message: %c\n",buf);
           }
       }
        buf ++;  // 消息数据改变
        cnt ++;
        rt_thread_mdelay(5);
   }
}

/* 消息队列初始化 */
int msgq_sample(void)
{
  rt_err_t re;
  /* 初始化消息队列 */
  re = rt_mq_init(&mq,  // 消息队列控制块
                  "mq1",  // 消息队列名
                  &msg_pool[0],  // 消息队列内存池
                  1,  // 每个消息的大小
                  sizeof(msg_pool),  // 存放消息的数目
                  RT_IPC_FLAG_FIFO); // 分配消息的策略
  if(re != RT_EOK)
  {
      rt_kprintf("init message queue failed!\n");
      return -1;
  }
  /* 线程1 */
  rt_thread_init(&thread1,
                 "thread1",
                 thread1_entry,
                 RT_NULL,
                 &thread1_stack[0],
                 sizeof(thread1_stack),
                 25,
                 5);
  rt_thread_startup(&thread1);
  /* 线程2 */
  rt_thread_init(&thread2,
                 "thread2",
                 thread2_entry,
                 RT_NULL,
                 &thread2_stack[0],
                 sizeof(thread2_stack),
                 25,
                 5);
  rt_thread_startup(&thread2);

  return 0;
}

MSH_CMD_EXPORT(msgq_sample,message queue sample);


2. 测试结果

在这里插入图片描述
在这里插入图片描述

详细文档
链接

### 嵌入式 Linux 线程间通信消息队列实现 #### 消息队列概述 在嵌入式Linux环境下,线程间通信可以通过多种方式进行,其中一种高效的方式就是使用消息队列消息队列是一种跨进程的数据结构,允许一个或多个进程向队列中放入消息,并由其他进程读取这些消息[^4]。 #### 创建初始化消息队列 为了在线程之间建立有效的通信通道,首先需要创建并初始化一个消息队列: ```c #include <mqueue.h> #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ // 定义消息队列名称 #define QUEUE_NAME "/my_queue" // 设置最大消息数量每条消息的最大长度 #define MAX_MESSAGES 10 #define MESSAGE_SIZE 256 mqd_t mq; // 打开或创建一个新的消息队列 struct mq_attr attr; attr.mq_flags = 0; attr.mq_maxmsg = MAX_MESSAGES; attr.mq_msgsize = MESSAGE_SIZE; attr.mq_curmsgs = 0; mq = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr); if (mq == (mqd_t)-1) { perror("Failed to open message queue"); } ``` 这段代码展示了如何定义消息队列的相关参数,并尝试打开已存在的同名消息队列;如果不存在,则按照指定属性创建新的消息队列[^5]。 #### 发送消息消息队列 一旦成功建立了消息队列,就可以通过`mq_send()`函数来发送消息给目标队列: ```c char *message = "Hello from sender thread!"; ssize_t msg_len = strlen(message); if (mq_send(mq, message, msg_len, 0) != 0){ perror("Message send failed"); } printf("Sent %zd bytes\n", msg_len); ``` 这里展示了一个简单的例子,在此例中,字符串形式的消息被写入之前创建好的消息队列中。 #### 接收来自消息队列消息 接收端可以调用`mq_receive()`从消息队列里获取最新的消息: ```c char buffer[MESSAGE_SIZE]; unsigned int priority; ssize_t num_bytes_received = mq_receive(mq, buffer, sizeof(buffer), &priority); if(num_bytes_received >= 0){ printf("Received message: \"%s\"\n", buffer); } else { perror("Receive error"); } // 关闭消息队列 mq_close(mq); ``` 上述代码片段实现了从消息队列中读取消息的功能,并将其内容打印出来。最后记得关闭不再使用的消息队列以释放资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值