Rt-thread: 消息队列

Message queue的结构如下:

 

 1 Parent属于内核对象,通过这个成员可以将消息队列挂到系统对象容器里面. Parent其实是一个ipc结构体,里面包含了挂起的线程

 

 

初始化状态如下:

 

2 msg_pool 是存放消息池的开始地址

3 msg_size 是每条消息的大小

4 max_msg 是最多的消息个数

5 entry:队列中的消息索引,记录消息队列的消息个数

6 msg_queue_head/msg_queue_tail/msg_queue_free 链表头,尾指针,以及指向空闲节点的指针

消息队列初始化后状态参考下图。

 

 

消息发送

线程或者中断服务程序都可以给消息队列发送消息。当发送消息时,消息队列对象先从空闲消息链表上取下一个空闲消息块,把线程或者中断服务程序发送的消息内容复制到消息块上,然后把该消息块挂到消息队列的尾部。当且仅当空闲消息链表上有可用的空闲消息块时,发送者才能成功发送消息;当空闲消息链表上无可用消息块,说明消息队列已满,此时,发送消息的的线程或者中断程序会收到一个错误码(-RT_EFULL)

 

(a)      首先从空闲队列中取出一个消息,如果空闲队列中没有可用信息块了,消息队列已满,则返回-RT_EFULL。每次申请后msg_queue_free指针则后移

 

 

示意图如下

 

 

(b)      取出消息后,将消息放到msg_queue_tail中去。并同时更新msg_queue_head的值

 

 

示意图如下

 

 

(c)     此时在消息队列中已经发送了消息。则看等待队列是否有任务在等待消息。如果有的话则将任务从挂起列表中恢复,并开启一次调度

 

 

消息接受

(a)     检查队列的消息是否为0,如果没有消息且timeout ==0 则立即返回

 

 (b)  如果消息队列为空,但是等待时间大于0,则将当前任务挂起,并启动一个定时器并发起一个线程调度

 

 

(c)     如果队列中有消息。则从消息队列头部msg_queue_head中取出消息。并拷贝到指定的存储地址buffer。拷贝消息的大小为size,大小不能超过创建消息队列时候已经定义的消息大小msg_size.

 

 

示意图如下:

 

 

获取一个消息后,消息队列上的头链表消息被转移到空闲消息链表中,这样就可以保证消息队列的循环利用。而不会导致头链表指针移动到队列尾部时没有可用的消息节点。

 

posted @   red_leaf_412  阅读(1934)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2019-03-31 linux c编程:记录锁
2018-03-31 python+NLTK 自然语言学习处理三:如何在nltk/matplotlib中的图片中显示中文
点击右上角即可分享
微信分享提示