基础篇_06_IPC之邮箱及消息队列
邮箱和消息队列,都是在需要数据交换的场景下使用。
那么首先,先介绍邮箱。邮箱有一个具体的大小,邮箱内接收的数据的个数,不能超过邮箱总大小的四分之一。
1.邮箱的创建&消息队列的创建
/*静态邮箱的创建*/
static struct rt_mailbox static_mailbox;
static char mb_pool[2048];rt_mb_init(&static_mailbox, "name", &mb_pool[0], sizeof(mb_pool)/4, run_flag);/*动态邮箱的创建*/
static rt_mailbox_t dynamic_mailbox = RT_NULL;dynamic_mailbox = rt_mb_creat("name", 512, run_flag);
邮件的每条消息所占的空间都是固定的,即四个字节。邮箱一定要先创建一个邮箱池,由于每条消息都会占用四字节,所以实际上能放置的邮件数目为总空间的1/4;但是消息队列的空间大小却是可以自己分配的,下面是消息队列的创建:
/*静态消息队列的创建*/
static struct rt_messagequeue static_mq;
static rt_uint8_t msq_pool[2048];rt_mq_init(&static_mq,"name",&msq_pool[0],a message of size,sizeof(msq_pool),type);/*动态消息队列的创建*/
static rt_mq_t dynamic_mq = RT_NULL;
static rt_uint8_t msq_pool[2018];dynamic_mq = rt_mq_creat("name", a message of size, max number,type);/*type是指类型,是先进先出的堆模式,还是伴随优先级模式*///常用 RT_IPC_FLAG_FIFO RT_IPC_FLAG_PRIO
a message of size 指每个信息的大小,可以自定义;
2.邮箱的发送&消息队列的发送
/*邮件的发送*//*只管发送,不管接受到接否不到*/
rt_mb_send(&static_mailbox,(rt_uint32_t)&mb_str1[0]);/*会发送消息,等待发出,在规定时间内如果未发送到就持续发送,常用RT_WAITING_FOREVER*/
rt_mb_send_wait(&static_mailbox,9rt_uint32_t)&mb_str1[0],time);/*邮件的接收*/
char *str;
rt_mb_rev(&static_mailbox,(rt_uint32_t)&srt,time);/*time指等待时间,支持永久等待*/
// RT_WAITING_FOREVER
邮箱的发送,通过最下面的例子,大家估计已经发现了有三个特点:一,邮箱只能存放邮件数目为总空间的1/4,如20个空间,一个邮件是4个字节,只能存放5组数据;二,邮箱池内并不存放要发送的数据;三,数据发送最多能做到等待确保发送成功,然而并不能加急。
/*消息队列的发送*/
char buff = 'A';/*发送数据到消息队列*/
rt_mq_send(&static_mailbox,&buff,size);/*发送紧急信息,可插队*/
rt_mq_urgent(&static_mailbox,&buff,size);/*size指发送的数据到消息队列的数据大小*/
对于消息队列,发送的数据,并不是直接传送地址,而是把字符段复制到新地址,而不是简单的地址传送。消息队列和邮箱的区别就在这些地方。
3.邮箱的删除&消息队列的删除
/*邮箱的删除*//*动态邮箱的删除*/
rt_mb_delete(dynamic_mailbox);/*静态邮箱的删除*/
rt_mb_detach(&static_mailbox);
4.邮箱的例程
/* 邮箱控制块 */
static struct rt_mailbox mb;
/* 用于放邮件的内存池 */
static char mb_pool[20];static char mb_str1[] = "I'm a mail!";
static char mb_str2[] = "this is another mail!";
static char mb_str3[] = "over";ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;/* 线程1入口 */
static void thread1_entry(void *parameter)
{char *str;while (1){rt_kprintf("thread1: try to recv a mail\n");/* 从邮箱中收取邮件 */if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK){rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);if (str == mb_str3)break;/* 延时100ms */rt_thread_mdelay(500);}}/* 执行邮箱对象脱离 */rt_mb_detach(&mb);
}ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;/* 线程2入口 */
static void thread2_entry(void *parameter)
{rt_uint8_t count;rt_err_t result;count = 0;while (count < 20){count ++;if (count & 0x1){/* 发送mb_str1地址到邮箱中 */result = rt_mb_send(&mb, (rt_uint32_t)&mb_str1);if(-RT_EFULL == result){//邮箱满了rt_kprintf("mailbox is fulled\n");return ;}}else{/* 发送mb_str2地址到邮箱中 */rt_mb_send(&mb, (rt_uint32_t)&mb_str2);}rt_kprintf("send a message\n");/* 延时200ms */rt_thread_mdelay(50);}/* 发送邮件告诉线程1,线程2已经运行结束 */rt_mb_send(&mb, (rt_uint32_t)&mb_str3);
}/*例程打印信息*/
/*
thread1: try to recv a mailsend a messagethread1: get a mail from mailbox, the content:I'm a mail!send a messagesend a messagesend a messagesend a messagesend a messagemailbox is fulledthread1: try to recv a mailthread1: get a mail from mailbox, the content:this is another mail!thread1: try to recv a mailthread1: get a mail from mailbox, the content:I'm a mail!thread1: try to recv a mailthread1: get a mail from mailbox, the content:this is another mail!thread1: try to recv a mailthread1: get a mail from mailbox, the content:I'm a mail!thread1: try to recv a mailthread1: get a mail from mailbox, the content:this is another mail!thread1: try to recv a mail
*/
邮箱的使用场景:需要发送消息的条件,打算和消息队列和信号实验解决后再来做具体实验。
5.消息队列的例程
/* 消息队列控制块 */
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;
/* 线程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 msg from msg queue, the content:%c\n", buf);if (cnt == 19){break;}}/* 延时50ms */cnt++;rt_thread_mdelay(50);}rt_kprintf("thread1: detach mq \n");rt_mq_detach(&mq);
}ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
/* 线程2入口 */
static void thread2_entry(void *parameter)
{int result;char buf = 'A'; rt_uint8_t cnt = 0;while (1){if (cnt == 8){/* 发送紧急消息到消息队列中 */result = rt_mq_urgent(&mq, &buf, 1);if (result != RT_EOK){rt_kprintf("rt_mq_urgent ERR\n");}else{rt_kprintf("thread2: send urgent message - %c\n", buf);}}else if (cnt >= 20)/* 发送20次消息之后退出 */{rt_kprintf("message queue stop send, thread2 quit\n");break;}else{/* 发送消息到消息队列中 */result = rt_mq_send(&mq, &buf, 1);if (result != RT_EOK){rt_kprintf("rt_mq_send ERR\n");}rt_kprintf("thread2: send message - %c\n", buf);}buf++;cnt++;/* 延时5ms */rt_thread_mdelay(5);}
}/*打印信息*/
/*
thread2: send message - Athread1: recv msg from msg queue, the content:Athread2: send message - Bthread2: send message - Cthread2: send message - Dthread2: send message - Ethread2: send message - Fthread1: recv msg from msg queue, the content:Bthread2: send message - Gthread2: send message - Hthread2: send urgent message - Ithread2: send message - Jthread2: send message - Kthread1: recv msg from msg queue, the content:Ithread2: send message - Lthread2: send message - Mthread2: send message - Nthread2: send message - Othread2: send message - Pthread1: recv msg from msg queue, the content:Cthread2: send message - Qthread2: send message - Rthread2: send message - Sthread2: send message - Tmessage queue stop send, thread2 quitthread1: recv msg from msg queue, the content:Dthread1: recv msg from msg queue, the content:Ethread1: recv msg from msg queue, the content:Fthread1: recv msg from msg queue, the content:Gthread1: recv msg from msg queue, the content:Hthread1: recv msg from msg queue, the content:Jthread1: recv msg from msg queue, the content:Kthread1: recv msg from msg queue, the content:Lthread1: recv msg from msg queue, the content:Mthread1: recv msg from msg queue, the content:Nthread1: recv msg from msg queue, the content:Othread1: recv msg from msg queue, the content:Pthread1: recv msg from msg queue, the content:Qthread1: recv msg from msg queue, the content:Rthread1: recv msg from msg queue, the content:Sthread1: recv msg from msg queue, the content:Tthread1: detach mq */
消息队列可以插队,邮箱不可以插队。
基础篇_06_IPC之邮箱及消息队列相关推荐
- FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)
我们在前面单独介绍过FreeRTOS的任务通知和消息队列, 但是在FreeRTOS中任务间的通讯还有信号量,邮箱,事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 ..增 ...
- uCos中的邮箱和消息队列
文章目录 1. 背景 2. 直接通信与间接通信 3. 消息机制 4. 消息队列 5. ucos-ii中实现 5.1. 任务创建 5.2. 发送消息 5.3. 等待消息 1. 背景 前段时间老师上课讲到 ...
- ucosii事件控制块------消息邮箱与消息队列
UCOSII 使用叫做事件控制块(ECB)的数据结构来描述诸如信号量.邮箱(消息邮箱)和消息队列这些事件 #define OS_EVENT_EN (((OS_Q_EN > 0u) &&a ...
- 7.3 TensorFlow笔记(基础篇):加载数据之从队列中读取
前言 整体步骤 在TensorFlow中进行模型训练时,在官网给出的三种读取方式,中最好的文件读取方式就是将利用队列进行文件读取,而且步骤有两步: 1. 把样本数据写入TFRecords二进制文件 2 ...
- RT-Thread 线程同步及通信 -- 信号量、互斥量、事件、邮箱、消息队列
目录 一 RT-Thread 信号量 二 RT-Thread 互斥量 三 RT-Thread 事件标志组 四 RT-Thread 邮箱 五 RT-Thread 消息队列 一 RT-Thre ...
- 分享一篇关于使用阿里云消息队列中遇到的坑
相信很多小伙伴都在开发中使用过消息队列,尤其是高并发的情况,一般可以在缓存中操作数据,然后通过消息异步处理业务逻辑,操作数据库等. 本人所在的公司使用了阿里云的消息队列和RabbitMQ,据说使用阿里 ...
- ucosii中消息队列、消息邮箱、信号量的区别
1.用信号量进行行为同步时,只能提供同步的时刻信息,不能提供内容信息.若被控制方要求得到控制方的内容信息时,可以使用消息邮箱或消息队列. 2.但由于消息邮箱里只能存放一条消息,所以使用消息邮箱进行任务 ...
- 智能家居DIY连载教程(2)——在实际项目中运用消息队列与邮箱
前言 千呼万唤始出来,智能家居 DIY 教程连载第二篇终于登场了!本文将重点给大家介绍如何将消息队列与邮箱运用到实际项目中去.一起来看看吧~ DIY 回顾上期: 1.智能家居DIY连载教程(1)--如 ...
- Kafka消息队列 入门到精通 看这一篇就够了
文章目录 第一章 概述 1.1 Kafka 的定义及特点 1.2 消息队列的介绍 1.3 Kafka 的基础架构 第二章 入门 2.1 Kafka 的安装部署 2.2 Kafka 命令行操作 第三章 ...
最新文章
- Linux shell 学习笔记(6)— vim 编辑器使用方法及技巧
- Java项目:家居购物商城系统(java+html+jdbc+mysql)
- 亮相2018CES:解读阿里云IoT筹谋全球物联网市场的一盘大棋!
- 数据结构及算法基础--优先队列(Priority Queue)
- Uniform Grid Quadtree kd树 Bounding Volume Hierarchy R树 搜索
- Java多线程知识小抄集(四)——完结
- mysql列别名引用_引用聚合列的MySQL别名
- 项目实战-药品采购系统-day01
- 【粉丝投稿】人在职场,说话要小心!
- 灵活控制 Hibernate 的日志或 SQL 输出,以便于诊断
- php点赞,php如何实现点赞
- JNI介绍及简单实例
- JDK8高性能队列“Disruptor“
- MR_LINUX_DRIVER安装教程,ovito安装说明(windows+linux)
- java 添加 psd_psd缩略图生成上传解决方案
- linux awk 打印最后一列,使用awk打印从第n个到最后一个的所有列
- Python 用turtle画多个八边形组成的蜘蛛网
- 系统架构设计——DDD设计框架基本学习
- win 运行scrapy warring UserWarning: You do not have a working installation of the service_identity mo
- Maya---倒角命令
热门文章
- linux添加硬盘及分区格式化
- 大佬说:怎么手写一个Tomcat然后给这个Tomcat 部署项目并且成功处理请求 ? 我TM当时就吓尿了!
- 【深度学习基础-14】回归中的相关系数r和决定系数R^2
- 计算机专业毕业论文java毕业设计网站SSH人事管理系统|人力请假考勤工资人事奖惩[包运行成功]
- 创新从未止步,华为智慧生活全场景新品齐发
- [转帖]关于主板、中小板、创业板、新三板,再也不会傻傻分不清楚啦!
- oracle 王景田_埃里森:将通过云计算推动公司增长 而非并购
- 跟着知识追寻者学BeautifulSoup,你学不会打不还口,骂不还手
- c语言姚英语好吗,姚老师互动问答会 # 问题006:根据种子法则,我要学好英语就要先去教别人英语,那我自己还要不要继续学习呢?...
- C++修炼之筑基期第四层 ——透过日期类看运算符重载 | 赋值运算符重载 | 取地址操作符重载