23 鸿蒙LiteOS 消息队列(Queue)实战教程:任务间数据传递详解
本文介绍了鸿蒙OpenHarmony LiteOS中的消息队列(Queue)机制,用于实现任务间数据传递。消息队列作为内核对象,采用FIFO原则,允许发送方和接收方异步通信。文章详细讲解了消息队列的核心概念、API接口,并提供了完整的可运行示例代码。该示例展示了如何创建消息队列、发送线程每秒递增数字、接收线程阻塞等待数据的过程。关键特性包括:FIFO原则、阻塞机制、支持任意数据类型传递等。消息队列
鸿蒙LiteOS 消息队列(Queue)实战教程:任务间数据传递详解
一、前言
在鸿蒙 OpenHarmony LiteOS 多任务开发中,任务与任务之间经常需要传递数据。
信号量只能做“通知”,互斥锁只能做“保护”,而消息队列是专门用来在任务之间传递数据的内核工具。
本文基于官方标准示例,讲解消息队列原理、API、代码解析、运行现象,帮你快速掌握任务间通信。
哔站视频《【RK2206 鸿蒙LiteOS 实战 08】队列 队列是什么 任务之间如何传递消息 真正的任务间数据通信》:https://www.bilibili.com/video/BV13ZLw6KEtL/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《【RK2206 鸿蒙LiteOS 实战 07】什么是互斥,互斥有什么用》:https://www.bilibili.com/video/BV1ed5X61E7t/
哔站视频《06:RK2206 OpenHarmonyOS 鸿蒙 软件定时器与硬件定时器区别 软件定时器与任务区别 软件定时器实战》:https://www.bilibili.com/video/BV1w3546DEBS/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《05:RK2206 OpenHarmonyOS 鸿蒙 什么是信号量 为什么需要信号量 代码演示》:https://www.bilibili.com/video/BV1to5W6pETF/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《04:RK2206 OpenHarmonyOS 鸿蒙 任务实战》:https://www.bilibili.com/video/BV15R5E6JEHy/
哔站视频《03:RK2206 鸿蒙 LiteOS 如何通过控制编译选项编译不同案例》:https://www.bilibili.com/video/BV15e5J6QEGY/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《02:RK2206 鸿蒙 LiteOS bin 文件 烧写》:https://www.bilibili.com/video/BV1pcRdBaEAt/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《01:RK2206 鸿蒙 LiteOS ubuntu 开发环境 全程 安装配置》:https://www.bilibili.com/video/BV1nrRkBoEMR/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
二、消息队列核心概念
1. 什么是消息队列
消息队列是一种内核对象,类似于数据管道,可以在任务与任务之间传递数据。
- 先进先出(FIFO)
- 发送方把数据放进队列
- 接收方从队列取出数据
- 队列空/满时,任务会自动阻塞等待
2. 消息队列作用
- 任务间数据传递(发数字、发字符串、发结构体)
- 解耦任务:发送方和接收方不需要同时运行
- 异步通信:发送完不用等接收方处理
3. 核心API
| 函数 | 作用 |
|---|---|
LOS_QueueCreate |
创建消息队列 |
LOS_QueueWrite |
向队列发送数据 |
LOS_QueueRead |
从队列读取数据 |
LOS_QueueDelete |
删除队列 |
三、完整可运行源码
#include "los_task.h"
#include "ohos_init.h"
#define MSG_QUEUE_LENGTH 16
#define BUFFER_LEN 50
static unsigned int m_msg_queue;
/***************************************************************
* 函数名称: msg_write_thread
* 说 明: 队列写线程:发送数据
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void msg_write_thread(void *arg)
{
unsigned int data = 0;
unsigned int ret = LOS_OK;
while (1)
{
data++;
// 发送数据到队列
ret = LOS_QueueWrite(m_msg_queue, (void *)&data, sizeof(data), LOS_WAIT_FOREVER);
if (LOS_OK != ret)
{
printf("%s write Message Queue msg fail ret:0x%x\n", __func__, ret);
}
else
{
printf("%s write Message Queue msg:%u\n", __func__, data);
}
LOS_Msleep(1000); // 每秒发一次数据
}
}
/***************************************************************
* 函数名称: msg_read_thread
* 说 明: 队列读线程:接收数据
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void msg_read_thread(void *arg)
{
unsigned int addr;
unsigned int ret = LOS_OK;
unsigned int *pData = NULL;
while (1)
{
// 阻塞等待接收数据
ret = LOS_QueueRead(m_msg_queue, (void *)&addr, BUFFER_LEN, LOS_WAIT_FOREVER);
if (ret == LOS_OK)
{
pData = (unsigned int *)addr;
printf("%s read Message Queue msg:%u\n", __func__, *pData);
}
else
{
printf("%s read Message Queue fail ret:0x%x\n", __func__, ret);
}
}
}
/***************************************************************
* 函数名称: queue_example
* 说 明: 队列初始化入口
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void queue_example()
{
unsigned int thread_id1;
unsigned int thread_id2;
TSK_INIT_PARAM_S task1 = {0};
TSK_INIT_PARAM_S task2 = {0};
unsigned int ret = LOS_OK;
// 创建消息队列
ret = LOS_QueueCreate("queue", MSG_QUEUE_LENGTH, &m_msg_queue, 0, BUFFER_LEN);
if (ret != LOS_OK)
{
printf("Falied to create Message Queue ret:0x%x\n", ret);
return;
}
// 创建发送线程
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)msg_write_thread;
task1.uwStackSize = 2048;
task1.pcName = "msg_write_thread";
task1.usTaskPrio = 24;
ret = LOS_TaskCreate(&thread_id1, &task1);
if (ret != LOS_OK)
{
printf("Falied to create msg_write_thread ret:0x%x\n", ret);
return;
}
// 创建接收线程
task2.pfnTaskEntry = (TSK_ENTRY_FUNC)msg_read_thread;
task2.uwStackSize = 2048;
task2.pcName = "msg_read_thread";
task2.usTaskPrio = 25;
ret = LOS_TaskCreate(&thread_id2, &task2);
if (ret != LOS_OK)
{
printf("Falied to create msg_read_thread ret:0x%x\n", ret);
return;
}
}
APP_FEATURE_INIT(queue_example);
四、代码逻辑解析
1. 核心流程
- 创建消息队列
- 创建发送线程:每秒发一个数字
- 创建接收线程:一直阻塞等数据
- 数据通过队列从发送方 → 接收方
2. 关键点
MSG_QUEUE_LENGTH 16:队列最多缓存16条消息BUFFER_LEN 50:每条消息最大50字节LOS_WAIT_FOREVER:队列空/满时阻塞等待
五、运行打印效果

六、消息队列重要特性
- FIFO 先进先出
- 发送/接收都会阻塞
- 队列满 → 发送阻塞
- 队列空 → 接收阻塞
- 可传递任意数据:数字、字符串、结构体
- 真正的任务间数据通信
七、总结
- 消息队列 = 任务间数据传递管道
- 发送方写数据,接收方读数据
- 队列空/满时自动阻塞,不占CPU
- 鸿蒙LiteOS中最常用任务间通信方式
更多推荐


所有评论(0)