邮箱和消息队列,都是在需要数据交换的场景下使用。

那么首先,先介绍邮箱。邮箱有一个具体的大小,邮箱内接收的数据的个数,不能超过邮箱总大小的四分之一。

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之邮箱及消息队列相关推荐

  1. FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列, 但是在FreeRTOS中任务间的通讯还有信号量,邮箱,事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 ..增 ...

  2. uCos中的邮箱和消息队列

    文章目录 1. 背景 2. 直接通信与间接通信 3. 消息机制 4. 消息队列 5. ucos-ii中实现 5.1. 任务创建 5.2. 发送消息 5.3. 等待消息 1. 背景 前段时间老师上课讲到 ...

  3. ucosii事件控制块------消息邮箱与消息队列

    UCOSII 使用叫做事件控制块(ECB)的数据结构来描述诸如信号量.邮箱(消息邮箱)和消息队列这些事件 #define OS_EVENT_EN (((OS_Q_EN > 0u) &&a ...

  4. 7.3 TensorFlow笔记(基础篇):加载数据之从队列中读取

    前言 整体步骤 在TensorFlow中进行模型训练时,在官网给出的三种读取方式,中最好的文件读取方式就是将利用队列进行文件读取,而且步骤有两步: 1. 把样本数据写入TFRecords二进制文件 2 ...

  5. RT-Thread 线程同步及通信 -- 信号量、互斥量、事件、邮箱、消息队列

    目录 一  RT-Thread 信号量 二  RT-Thread 互斥量 三  RT-Thread 事件标志组 四  RT-Thread 邮箱 五  RT-Thread 消息队列 一  RT-Thre ...

  6. 分享一篇关于使用阿里云消息队列中遇到的坑

    相信很多小伙伴都在开发中使用过消息队列,尤其是高并发的情况,一般可以在缓存中操作数据,然后通过消息异步处理业务逻辑,操作数据库等. 本人所在的公司使用了阿里云的消息队列和RabbitMQ,据说使用阿里 ...

  7. ucosii中消息队列、消息邮箱、信号量的区别

    1.用信号量进行行为同步时,只能提供同步的时刻信息,不能提供内容信息.若被控制方要求得到控制方的内容信息时,可以使用消息邮箱或消息队列. 2.但由于消息邮箱里只能存放一条消息,所以使用消息邮箱进行任务 ...

  8. 智能家居DIY连载教程(2)——在实际项目中运用消息队列与邮箱

    前言 千呼万唤始出来,智能家居 DIY 教程连载第二篇终于登场了!本文将重点给大家介绍如何将消息队列与邮箱运用到实际项目中去.一起来看看吧~ DIY 回顾上期: 1.智能家居DIY连载教程(1)--如 ...

  9. Kafka消息队列 入门到精通 看这一篇就够了

    文章目录 第一章 概述 1.1 Kafka 的定义及特点 1.2 消息队列的介绍 1.3 Kafka 的基础架构 第二章 入门 2.1 Kafka 的安装部署 2.2 Kafka 命令行操作 第三章 ...

最新文章

  1. Linux shell 学习笔记(6)— vim 编辑器使用方法及技巧
  2. Java项目:家居购物商城系统(java+html+jdbc+mysql)
  3. 亮相2018CES:解读阿里云IoT筹谋全球物联网市场的一盘大棋!
  4. 数据结构及算法基础--优先队列(Priority Queue)
  5. Uniform Grid Quadtree kd树 Bounding Volume Hierarchy R树 搜索
  6. Java多线程知识小抄集(四)——完结
  7. mysql列别名引用_引用聚合列的MySQL别名
  8. 项目实战-药品采购系统-day01
  9. 【粉丝投稿】人在职场,说话要小心!
  10. 灵活控制 Hibernate 的日志或 SQL 输出,以便于诊断
  11. php点赞,php如何实现点赞
  12. JNI介绍及简单实例
  13. JDK8高性能队列“Disruptor“
  14. MR_LINUX_DRIVER安装教程,ovito安装说明(windows+linux)
  15. java 添加 psd_psd缩略图生成上传解决方案
  16. linux awk 打印最后一列,使用awk打印从第n个到最后一个的所有列
  17. Python 用turtle画多个八边形组成的蜘蛛网
  18. 系统架构设计——DDD设计框架基本学习
  19. win 运行scrapy warring UserWarning: You do not have a working installation of the service_identity mo
  20. Maya---倒角命令

热门文章

  1. linux添加硬盘及分区格式化
  2. 大佬说:怎么手写一个Tomcat然后给这个Tomcat 部署项目并且成功处理请求 ? 我TM当时就吓尿了!
  3. 【深度学习基础-14】回归中的相关系数r和决定系数R^2
  4. 计算机专业毕业论文java毕业设计网站SSH人事管理系统|人力请假考勤工资人事奖惩[包运行成功]
  5. 创新从未止步,华为智慧生活全场景新品齐发
  6. [转帖]关于主板、中小板、创业板、新三板,再也不会傻傻分不清楚啦!
  7. oracle 王景田_埃里森:将通过云计算推动公司增长 而非并购
  8. 跟着知识追寻者学BeautifulSoup,你学不会打不还口,骂不还手
  9. c语言姚英语好吗,姚老师互动问答会 # 问题006:根据种子法则,我要学好英语就要先去教别人英语,那我自己还要不要继续学习呢?...
  10. C++修炼之筑基期第四层 ——透过日期类看运算符重载 | 赋值运算符重载 | 取地址操作符重载