RT-Thread快速入门(五)之邮箱
前言在上一篇中我们学习了消息队列——它可以传递任意大小的数据非常灵活。但它的内部涉及链表操作和memcpy如果只是传递一些很小的数据比如状态码、计数值、指针地址用消息队列就有点杀鸡用牛刀了。RT-Thread 提供了另一种轻量级的线程间通信机制——邮箱Mailbox。一句话总结传递小数据用邮箱传递大数据用消息队列。目录前言一、邮箱的特性1.1 邮箱的本质1.2 核心特性1.3 邮箱 vs 消息队列二、邮箱操作 API2.1 创建/初始化2.2 删除/脱离2.3 发送邮件2.4 接收邮件三、完整示例四、邮箱的使用技巧4.1 通过邮箱传递指针4.2 邮箱满时的阻塞发送五、邮箱 vs 消息队列 选型指南六、总结一、邮箱的特性1.1 邮箱的本质邮箱的底层实现是环形缓冲区Ring Buffer而非消息队列的链表结构写入端 读出端 ┌──────────┐ ┌────┬────┬────┬────┐ ┌──────────┐ │ 线程A │───→│ │ │ │ │───→│ 线程B │ ├──────────┤ │ ██ │ ██ │ ██ │ ██ │ ├──────────┤ │ 线程B │───→│ │ │ │ │───→│ ISR │ ├──────────┤ └────┴────┴────┴────┘ └──────────┘ │ ISR │───→ 环形缓冲区 └──────────┘ 每格 4 字节1.2 核心特性特性说明邮件大小每封邮件固定4 字节32 位系统上为一个rt_uint32_t底层结构环形缓冲区数组比链表的消息队列更高效存储能力可缓存一定数量的邮件发送内容任意 32 位数据可以是整数值也可以是指针阻塞访问空时读可阻塞满时写可阻塞超时机制支持超时等待1.3 邮箱 vs 消息队列对比项邮箱Mailbox消息队列Message Queue数据大小固定 4 字节任意大小内部实现环形缓冲区数组链表 memcpy效率⭐⭐⭐⭐⭐更高⭐⭐⭐ 中等内存开销小每个邮件 4 字节较大消息块 链表指针适用场景传递小数值 / 指针传递大数据 / 结构体紧急消息不支持rt_mb_urgent()支持rt_mq_urgent()选型口诀传数值用邮箱传结构体用消息队列。二、邮箱操作 API2.1 创建/初始化动态创建 —rt_mb_creatert_mailbox_t rt_mb_create(const char* name, rt_size_t size, // 邮箱容量邮件个数 rt_uint8_t flag); // RT_IPC_FLAG_FIFO / RT_IPC_FLAG_PRIO返回值成功返回邮箱句柄失败返回RT_NULL邮件缓冲区由函数内部动态分配// 示例创建可容纳 5 封邮件的邮箱 rt_mailbox_t mb rt_mb_create(mbox, 5, RT_IPC_FLAG_FIFO); if (mb RT_NULL) rt_kprintf(Failed to create mailbox!\n);静态初始化 —rt_mb_initrt_err_t rt_mb_init(rt_mailbox_t mb, // 邮箱句柄 const char* name, void* msgpool, // 预分配的缓冲区 rt_size_t size, // 邮箱容量邮件个数 rt_uint8_t flag);返回值成功返回RT_EOK注意size是邮件个数不是字节数。每个邮件占 4 字节所以size 缓冲区总字节 / 4// 示例静态初始化缓冲区 20 字节 → 可容纳 5 封邮件 static rt_uint32_t mb_pool[5]; static struct rt_mailbox mb; ​ rt_mb_init(mb, mbt, mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);2.2 删除/脱离// 删除动态创建的邮箱 rt_err_t rt_mb_delete(rt_mailbox_t mb); ​ // 脱离静态初始化的邮箱 rt_err_t rt_mb_detach(rt_mailbox_t mb);2.3 发送邮件RT-Thread 提供三个发送函数函数说明阻塞rt_mb_send(mb, value)发送普通邮件放到队尾❌ 满时返回-RT_EFULLrt_mb_send_wait(mb, value, timeout)等待发送满时阻塞✅ 满时阻塞等待/* 普通发送 */ rt_err_t rt_mb_send(rt_mailbox_t mb, rt_uint32_t value); ​ /* 等待发送 */ rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_uint32_t value, rt_int32_t timeout);参数value是rt_uint32_t类型即 32 位无符号整数可以传递整数值如状态码、计数值指针地址如(rt_uint32_t)ptr2.4 接收邮件rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, // 输出参数接收到的邮件值 rt_int32_t timeout);返回值RT_EOK成功 /-RT_ETIMEOUT超时 /-RT_ERROR错误三、完整示例本程序创建一个邮箱、1 个发送线程、1 个接收线程#include rtthread.h ​ /* 邮箱控制块和缓冲区静态方式 */ static struct rt_mailbox mb; static rt_uint32_t mb_pool[10]; // 可容纳 10 封邮件 ​ /* 线程句柄 */ static rt_thread_t thread1 RT_NULL; static rt_thread_t thread2 RT_NULL; ​ #define THREAD_PRIORITY 15 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 10 ​ /* 发送线程入口函数 */ static void thread1_entry(void *parameter) { rt_err_t result; int count 0; ​ while(1) { count; ​ /* 发送邮件数值自增 */ result rt_mb_send(mb, (rt_ubase_t)count); if (result ! RT_EOK) { rt_kprintf(rt_mb_send ERR\n); } else { rt_kprintf(rt_mb_send:%d\n\r, count); } ​ rt_thread_mdelay(10); } } ​ /* 接收线程入口函数 */ static void thread2_entry(void *parameter) { int val; ​ while(1) { /* 接收邮件永久等待 */ if (rt_mb_recv(mb, (rt_ubase_t *)val, RT_WAITING_FOREVER) RT_EOK) { rt_kprintf(rt_mb_recv:%d\n\r, val); } ​ rt_thread_mdelay(5); } } ​ int main(void) { rt_err_t result; ​ /* 1. 初始化邮箱 * mb_pool[10] 共 40 字节每个邮件 4 字节 * 容量 40 / 4 10 */ result rt_mb_init(mb, mbt, mb_pool[0], sizeof(mb_pool) / 4, // 邮箱容量 10 RT_IPC_FLAG_FIFO); // 先来先得 if (result ! RT_EOK) { rt_kprintf(rt_mb_init ERR\n); return -1; } ​ /* 2. 创建发送线程优先级 14较高 */ thread1 rt_thread_create(thread1, thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); if (thread1 ! RT_NULL) rt_thread_startup(thread1); ​ /* 3. 创建接收线程优先级 15 */ thread2 rt_thread_create(thread2, thread2_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (thread2 ! RT_NULL) rt_thread_startup(thread2); ​ return 0; }运行结果注意发送线程优先级更高14所以它先运行写入邮箱当邮箱满或调用mdelay(10)后挂起接收线程优先级 15才有机会读出。四、邮箱的使用技巧4.1 通过邮箱传递指针由于邮箱可以传递任意 32 位值因此也可以用来传递指针/* 发送端 */ char *message Hello RT-Thread!; rt_mb_send(mb, (rt_uint32_t)message); // 把指针地址当作邮件发送 ​ /* 接收端 */ char *msg; rt_mb_recv(mb, (rt_uint32_t *)msg, RT_WAITING_FOREVER); rt_kprintf(Received: %s\n, msg);⚠️ 确保指针指向的内存在线程生命周期内有效不要在接收方拿到地址后原始内存已被释放。4.2 邮箱满时的阻塞发送使用rt_mb_send_wait()可以在邮箱满时阻塞等待/* 如果邮箱满了等待 100 Tick约 100ms超时则返回 */ result rt_mb_send_wait(mb, 42, 100); if (result RT_EOK) rt_kprintf(Send OK\n); else if (result -RT_ETIMEOUT) rt_kprintf(Send timeout, mailbox full\n);五、邮箱 vs 消息队列 选型指南场景推荐使用原因传递数值状态码、计数值邮箱效率高内存开销小传递指针大块数据邮箱直接传 4 字节地址传递结构体中等大小消息队列消息队列支持任意大小数据传递不定长数据消息队列每个消息大小可不同需要多个数据缓冲消息队列链表结构更灵活实时性要求极高邮箱数组操作无动态内存分配六、总结知识点要点邮箱本质环形缓冲区数组每封邮件 4 字节动态创建rt_mb_create()— 内存由内核分配静态初始化rt_mb_init()— 需用户提供缓冲区容量 总字节 / 4发送邮件rt_mb_send()队尾 /rt_mb_urgent()队首紧急等待发送rt_mb_send_wait()满时阻塞接收邮件rt_mb_recv()— 支持超时等待传递内容32 位整数值 或 指针地址唤醒策略RT_IPC_FLAG_PRIO按优先级/RT_IPC_FLAG_FIFO按等待时间删除/脱离动态用rt_mb_delete()静态用rt_mb_detach()适用场景小数据数值/指针用邮箱大数据结构体用消息队列

相关新闻

SmartPack-Kernel-Manager安全指南:安全调优Android内核的7个关键步骤

SmartPack-Kernel-Manager安全指南:安全调优Android内核的7个关键步骤

SmartPack-Kernel-Manager安全指南:安全调优Android内核的7个关键步骤 【免费下载链接】SmartPack-Kernel-Manager Source code of SmartPack-Kernel Manager, the Ultimate Tool to Manage your Kernel 项目地址: https://gitcode.com/gh_mirrors/smar/SmartPack…

2026/7/12 18:44:29阅读更多 →
Chopper代码生成原理揭秘:source_gen如何简化HTTP客户端开发

Chopper代码生成原理揭秘:source_gen如何简化HTTP客户端开发

Chopper代码生成原理揭秘:source_gen如何简化HTTP客户端开发 【免费下载链接】chopper Chopper is an http client generator using source_gen and inspired from Retrofit. 项目地址: https://gitcode.com/gh_mirrors/ch/chopper Chopper是一个基于source_…

2026/7/12 18:44:29阅读更多 →
哈佛大学联合罗氏制药团队在Nat Med发表泛癌AI基础模型,仅通过肿瘤批量转录组数据就能预测免疫治疗效果

哈佛大学联合罗氏制药团队在Nat Med发表泛癌AI基础模型,仅通过肿瘤批量转录组数据就能预测免疫治疗效果

小罗碎碎念参考来源:Wanxiang Shen, Intae Moon, Thinh H. Nguyen, et al. Generalizable AI predicts immunotherapy outcomes across cancers and treatments. Nature Medicine, 2026.研究团队:哈佛大学医学院Marinka Zitnik实验室、罗氏制药研发团队如…

2026/7/12 18:44:29阅读更多 →
Nokhwa与WebAssembly:浏览器环境下的摄像头捕获终极指南

Nokhwa与WebAssembly:浏览器环境下的摄像头捕获终极指南

Nokhwa与WebAssembly:浏览器环境下的摄像头捕获终极指南 【免费下载链接】nokhwa Cross Platform Rust Library for Powerful Webcam/Camera Capture 项目地址: https://gitcode.com/gh_mirrors/no/nokhwa 在当今Web应用开发中,浏览器端的摄像头访…

2026/7/12 19:54:39阅读更多 →
密评整改倒计时 15 天:达梦 DMJOB 日志“裸奔”惹大祸,我用 Java 旁路加密+盲索引,硬刚 5 个生死坑!

密评整改倒计时 15 天:达梦 DMJOB 日志“裸奔”惹大祸,我用 Java 旁路加密+盲索引,硬刚 5 个生死坑!

🔥关注墨瑾轩,带你探索编程的奥秘!🚀 🔥超萌技术攻略,轻松晋级编程高手🚀 🔥技术宝库已备好,就等你来挖掘🚀 🔥订阅墨瑾轩,智趣学习不…

2026/7/12 19:54:39阅读更多 →
树上椰子成熟度检测数据集VOC+YOLO格式1204张2类别

树上椰子成熟度检测数据集VOC+YOLO格式1204张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):1204标注数量(xml文件个数):1204标注数量(txt文件个数):1204标注类别…

2026/7/12 19:54:39阅读更多 →
砸了3000万把Oracle换成国产库,上线首日却被JDBC驱动和ORM方言按在地上摩擦——我手搓“生态兼容性自愈引擎”与“成熟度雷达”,给所有信创DBA敲响警钟!

砸了3000万把Oracle换成国产库,上线首日却被JDBC驱动和ORM方言按在地上摩擦——我手搓“生态兼容性自愈引擎”与“成熟度雷达”,给所有信创DBA敲响警钟!

,我花了一个月时间,把主流国产库的 JDBC 驱动源码、ORM 方言包和监控探针扒了个底朝天,并沉淀出了一套 “生态兼容性自愈引擎” 和 “成熟度自动化雷达”。 今天,我就把这套“信创保命指南”的核心代码扒干净。咖啡续上&#xff0…

2026/7/12 19:54:39阅读更多 →
Linux操作系统-软件包管理

Linux操作系统-软件包管理

Linux 软件包管理实战:RPM、YUM 与源码编译 引言 “怎么装个软件这么麻烦?” 这大概是很多 Linux 新手最头疼的问题。在 Windows 上,双击 .exe 一路 Next 就完事了;在 macOS 上,拖进 Applications 文件夹就行。但到了 …

2026/7/12 19:54:39阅读更多 →
Bonsai进阶技巧:10个实用功能帮你彻底优化前端bundle体积

Bonsai进阶技巧:10个实用功能帮你彻底优化前端bundle体积

Bonsai进阶技巧:10个实用功能帮你彻底优化前端bundle体积 【免费下载链接】bonsai Understand the tree of dependencies inside your webpack bundles, and trim away the excess. 项目地址: https://gitcode.com/gh_mirrors/bon/bonsai 想要快速提升前端应…

2026/7/12 19:49:39阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/11 16:20:28阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/11 23:15:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/11 18:12:23阅读更多 →