RT-Thread学习笔记(9):邮箱
目录
- 邮箱的概念
- 运作机制
- 邮箱的控制块
- 应用场合
- 参考
邮箱的概念
邮箱在操作系统中是一种常用的IPC通信方式,邮箱可以在线程与线程
之间。中断与线程
之间进行消息的传递,此外,邮箱相比于信号量与消息队列来说,其开销更低,效率更高,所以常用来做线程与线程、中断与线程间的通信。邮箱中的每一封邮件只能容纳固定的4字节内容
(STM32是32位处理系统,一个指针的大小即为4个字节,所以一封邮件恰好能够容纳一个指针
),当需要在线程间传递比较大的消息时,可以把指向一个缓冲区的指针作为邮件发送到邮箱中。
线程能够从邮箱里面读取邮件消息,当邮箱中的邮件是空时,根据用户自定义的阻塞时间决定是否挂起读取线程;当邮箱中有新邮件时,挂起的读取线程被唤醒,邮箱也是一种异步的通信方式。
通过邮箱,线程或中断服务函数可以将一个或多个邮件放入邮箱中。同样,一个或多个线程可以从邮箱中获得邮件消息。当有多个邮件发送到邮箱时,通常应将先进入邮箱的邮件先传给线程,也就是说,线程先得到的是最先进入邮箱的消息,即先进先出原则(FIFO)
,同时RT-Thread中的邮箱支持优先级,也就是说在所有等待邮件的线程中优先级最高的会先获得邮件。
RT-Thread中使用邮箱实现线程异步通信工作,具有如下特性:
- 邮件支持
先进先出
方式排队与优先级
排队方式,支持异步读写工作方式。- 发送与接收邮件均支持
超时机制
。- 一个线程能够从任意一个消息队列接收和发送邮件。
- 多个线程能够向同一个邮箱发送邮件和从中接收邮件。
- 邮箱中的每一封邮件只能容纳固定的4字节内容(可以存放地址)。
- 当队列使用结束后,需要通过删除邮箱以释放内存。
邮箱与消息队列很相似,消息队列中消息的长度是可以由用户配置的,但邮箱中邮件的大小却只能是固定容纳4字节的内容,所以,使用邮箱的开销是很小的,因为传递的只能是4字节以内的内容,那么其效率会更高。
运作机制
创建邮箱对象时会先创建一个邮箱对象控制块,然后给邮箱分配一块内存空间用来存放邮件,这块内存的大小等于邮件大小(4字节)与邮箱容量的乘积
,接着初始化接收邮件和发送邮件在邮箱中的偏移量
,接着再初始化消息队列,此时消息队列为空。
线程或者中断服务程序都可以给邮箱发送邮件,非阻塞方式的邮件发送过程能够安全的应用于中断服务中
,中断服务函数、定时器向线程发送消息的有效手段,而阻塞方式的邮件发送只能应用于线程
中。当发送邮件时,当且仅当邮箱还没满邮件的时候才能进行发送,如果邮箱已满,可以根据用户设定的等待时间进行等待,当邮箱中的邮件被收取而空出空间来时,等待挂起的发送线程将被唤醒继续发送的过程,当等待时间到了还未完成发送邮件,或者未设置等待时间,此时发送邮件失败,发送邮件的线程或者中断程序会收到一个错误码(-RT_EFULL)。线程发送邮件可以带阻塞,但在中断中不能采用任何带阻塞的方式发送邮件。
邮箱的控制块
struct rt_mailbox
{struct rt_ipc_object parent;rt_uint32_t* msg_pool; /* 邮箱缓冲区的开始地址 */rt_uint16_t size; /* 邮箱缓冲区的大小 */rt_uint16_t entry; /* 邮箱中邮件的数目 */rt_uint16_t in_offset, out_offset; /* 邮箱缓冲的进出指针 */rt_list_t suspend_sender_thread; /* 发送线程的挂起等待队列 */
};
typedef struct rt_mailbox* rt_mailbox_t;
应用场合
邮箱是一种简单的线程间消息传递方式,特点是开销比较低,效率较高。在 RT-Thread 操作系统的实现中能够一次传递一个 4 字节大小的邮件,并且邮箱具备一定的存储功能,能够缓存一定数量的邮件数 (邮件数由创建、初始化邮箱时指定的容量决定)。邮箱中一封邮件的最大长度是 4 字节,所以邮箱能够用于不超过 4 字节的消息传递。由于在 32 系统上 4 字节的内容恰好可以放置一个指针,因此当需要在线程间传递比较大的消息时,可以把指向一个缓冲区的指针作为邮件发送到邮箱中,即邮箱也可以传递指针,例如:
struct msg
{rt_uint8_t *data_ptr;rt_uint32_t data_size;
};
对于这样一个消息结构体,其中包含了指向数据的指针 data_ptr 和数据块长度的变量 data_size。当一个线程需要把这个消息发送给另外一个线程时,可以采用如下的操作:
struct msg* msg_ptr;msg_ptr = (struct msg*)rt_malloc(sizeof(struct msg));
msg_ptr->data_ptr = ...; /* 指向相应的数据块地址 */
msg_ptr->data_size = len; /* 数据块的长度 */
/* 发送这个消息指针给 mb 邮箱 */
rt_mb_send(mb, (rt_uint32_t)msg_ptr);
而在接收线程中,因为收取过来的是指针,而 msg_ptr 是一个新分配出来的内存块,所以在接收线程处理完毕后,需要释放相应的内存块
struct msg* msg_ptr;
if (rt_mb_recv(mb, (rt_uint32_t*)&msg_ptr) == RT_EOK)
{/* 在接收线程处理完毕后,需要释放相应的内存块 */rt_free(msg_ptr);
}
参考
本节笔记参考于:野火-《RT-Thread内核实现与应用开发实战》
韦东山 《RT-Thread完全开发手册之内核机制》
以及RT-Thread官网:邮箱
RT-Thread学习笔记(9):邮箱相关推荐
- (uC/OS-II学习笔记) 消息邮箱消息队列
原文出处: http://www.cnblogs.com/hebaichuanyeah 与信号量一样,消息邮箱与消息列队都是一种事件块. 消息邮箱可以在任务间实现信息传递. 比如,在任务1中发送一条消 ...
- RT-Thread 入门学习笔记 - 熟悉邮箱rt_mailbox的使用
简介 邮箱是用来传输邮件的,如果没人取件,会暂存下来. RT-Thread的邮箱,传递的是一个4字节(32位)值,可以传值,可以传指针(32位MCU,指针为32位). 邮箱使用比消息队列更精简,简单的 ...
- 源码学习笔记-网易邮箱登陆页面
不知道为什么出来效果不一样?上面是菜鸟编辑器,下面是记事本,可能缺少图片的原因 <html> <head> <title>111</title&g ...
- [Systemverilog学习笔记] Thread Communication-Event、Semaphore、mailbox
[Systemverilog学习笔记] Thread Communication-Event.Semaphore.mailbox 学习目标: 通过下文了解Event.Semaphore.mailbox ...
- 第98讲:使用SBT开发时动手解决rt.jar中CharSequence is broken等问题学习笔记
第98讲:使用SBT开发时动手解决rt.jar中CharSequence is broken等问题学习笔记 几乎所有从IDEA官网上下载安装在win上,采用默认方式自动运行的都 会遇到这个问题. er ...
- THREAD APC 《寒江独钓》内核学习笔记(4)
继续学习windows 中和线程有关系的数据结构: ETHREAD.KTHREAD.TEB 1. 相关阅读材料 <windows 内核原理与实现> --- 潘爱民 2. 数据结构分析 我们 ...
- GEE学习笔记一账号注册(只需要用谷歌邮箱就能注册成功)
小白辰某的GEE学习笔记一 gee账号注册的雷,我先踩为敬 为了申请成功我真的是看遍了知乎和csdn上所有的文章,以下随便写写我踩的雷点.本人写的小文章,统统都是纯干货,简单明了,新手必备(不吹不黑你 ...
- RT-Thread 邮箱(学习笔记)
本文参考自[野火EmbedFire]<RT-Thread内核实现与应用开发实战--基于STM32>,仅作为个人学习笔记.更详细的内容和步骤请查看原文(可到野火资料下载中心下载) 文章目录 ...
- Spring Boot学习笔记-基础(2)
Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...
- Spring Boot 2 学习笔记(2 / 2)
Spring Boot 2 学习笔记(1 / 2) - - - 45.web实验-抽取公共页面 46.web实验-遍历数据与页面bug修改 47.视图解析-[源码分析]-视图解析器与视图 48.拦截器 ...
最新文章
- 离ExtJS 4.1 beta发布只剩26个bug了
- require js define 函数
- 机房收费系统-- MDI子窗体显示技巧(续vb.net版)
- glutSolidSphere 用例
- MTK-TP(电阻屏校准程序ts_lib移植)
- Cachefiled
- 概述嵌入式设备驱动,教你怎么“玩”转嵌入式开发
- 写给90后快30岁的我们
- java 场景处理,最适合使用RxJava处理的四种场景
- 背景图怎么置于底层_Ps素材教程含有刻度的背景图
- Python画等高线以及标注
- 2.精通前端系列技术之JS模块化开发-深入学习seaJs(四)
- [Prescan] Prescan与Simulink联合
- python 概率分布_Python中的联合概率分布
- C语言-Switch 语句
- python爬虫项目(对博思平台社区话题信息进行爬取并保存)
- python 弱引用
- HTML+CSS+JS网页设计与制作期末大作业:网站——宏源山庄
- 利用七牛存储7天远程自动备份LINUX服务器
- 后端开发如何快速转前端开发
热门文章
- html如何把图片在背景图一半,img只显示图片一部分 或 css设置背景图片只显示图片指定区域...
- poky linux初探 -- 添加自己的内核食谱
- 银河麒麟连不上网怎么办
- “外卖式”售后服务体验来袭 沃丰科技ServiceGo让售后服务更智能
- 将一个Excel中的数据导入DataGrid中
- 报告|中国智能音箱已入局全球市场,双重商业模式迅速扩张
- fairyGUI的学习记录1
- 【Autopsy数字取证篇】Autopsy数字取证软件的下载安装与优化配置
- Log4j2 重大漏洞与解决方案
- GUI窗口不显示图片背景图片,和布局后不显示组件,的根本原因和解决办法