23 鸿蒙LiteOS 消息队列(Queue)实战教程:任务间数据传递详解

23 鸿蒙LiteOS 消息队列(Queue)实战教程:任务间数据传递详解 鸿蒙LiteOS 消息队列Queue实战教程任务间数据传递详解一、前言在鸿蒙 OpenHarmony LiteOS 多任务开发中任务与任务之间经常需要传递数据。信号量只能做“通知”互斥锁只能做“保护”而消息队列是专门用来在任务之间传递数据的内核工具。本文基于官方标准示例讲解消息队列原理、API、代码解析、运行现象帮你快速掌握任务间通信。哔站视频《【RK2206 鸿蒙LiteOS 实战 08】队列 队列是什么 任务之间如何传递消息 真正的任务间数据通信》https://www.bilibili.com/video/BV13ZLw6KEtL/?vd_source3a9dd7a328acafb09dd1b8d05f3e2bf7哔站视频《【RK2206 鸿蒙LiteOS 实战 07】什么是互斥互斥有什么用》https://www.bilibili.com/video/BV1ed5X61E7t/哔站视频《06RK2206 OpenHarmonyOS 鸿蒙 软件定时器与硬件定时器区别 软件定时器与任务区别 软件定时器实战》https://www.bilibili.com/video/BV1w3546DEBS/?vd_source3a9dd7a328acafb09dd1b8d05f3e2bf7哔站视频《05RK2206 OpenHarmonyOS 鸿蒙 什么是信号量 为什么需要信号量 代码演示》https://www.bilibili.com/video/BV1to5W6pETF/?vd_source3a9dd7a328acafb09dd1b8d05f3e2bf7哔站视频《04RK2206 OpenHarmonyOS 鸿蒙 任务实战》https://www.bilibili.com/video/BV15R5E6JEHy/哔站视频《03RK2206 鸿蒙 LiteOS 如何通过控制编译选项编译不同案例》https://www.bilibili.com/video/BV15e5J6QEGY/?spm_id_from333.1387.homepage.video_card.clickvd_source3a9dd7a328acafb09dd1b8d05f3e2bf7哔站视频《02RK2206 鸿蒙 LiteOS bin 文件 烧写》https://www.bilibili.com/video/BV1pcRdBaEAt/?spm_id_from333.1387.homepage.video_card.clickvd_source3a9dd7a328acafb09dd1b8d05f3e2bf7哔站视频《01RK2206 鸿蒙 LiteOS ubuntu 开发环境 全程 安装配置》https://www.bilibili.com/video/BV1nrRkBoEMR/?spm_id_from333.1387.homepage.video_card.clickvd_source3a9dd7a328acafb09dd1b8d05f3e2bf7二、消息队列核心概念1. 什么是消息队列消息队列是一种内核对象类似于数据管道可以在任务与任务之间传递数据。先进先出FIFO发送方把数据放进队列接收方从队列取出数据队列空/满时任务会自动阻塞等待2. 消息队列作用任务间数据传递发数字、发字符串、发结构体解耦任务发送方和接收方不需要同时运行异步通信发送完不用等接收方处理3. 核心API函数作用LOS_QueueCreate创建消息队列LOS_QueueWrite向队列发送数据LOS_QueueRead从队列读取数据LOS_QueueDelete删除队列三、完整可运行源码#includelos_task.h#includeohos_init.h#defineMSG_QUEUE_LENGTH16#defineBUFFER_LEN50staticunsignedintm_msg_queue;/*************************************************************** * 函数名称: msg_write_thread * 说 明: 队列写线程发送数据 * 参 数: 无 * 返 回 值: 无 ***************************************************************/voidmsg_write_thread(void*arg){unsignedintdata0;unsignedintretLOS_OK;while(1){data;// 发送数据到队列retLOS_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 * 说 明: 队列读线程接收数据 * 参 数: 无 * 返 回 值: 无 ***************************************************************/voidmsg_read_thread(void*arg){unsignedintaddr;unsignedintretLOS_OK;unsignedint*pDataNULL;while(1){// 阻塞等待接收数据retLOS_QueueRead(m_msg_queue,(void*)addr,BUFFER_LEN,LOS_WAIT_FOREVER);if(retLOS_OK){pData(unsignedint*)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 * 说 明: 队列初始化入口 * 参 数: 无 * 返 回 值: 无 ***************************************************************/voidqueue_example(){unsignedintthread_id1;unsignedintthread_id2;TSK_INIT_PARAM_S task1{0};TSK_INIT_PARAM_S task2{0};unsignedintretLOS_OK;// 创建消息队列retLOS_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.uwStackSize2048;task1.pcNamemsg_write_thread;task1.usTaskPrio24;retLOS_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.uwStackSize2048;task2.pcNamemsg_read_thread;task2.usTaskPrio25;retLOS_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中最常用任务间通信方式