为什么要用:
任务间的通信可以通过全局变量或者信号量来完成。全局变量虽然可以承载通信的内容,但是接收方无法意识到信息的到达,除非发送方向接收方发送一个信号量,或者接收方不断该全局变量;信号量可以立即使接收方知道某个事件的发生,但无法传递具体内容。用信号量进行通信就像我们只拨通别人的手机而不与之通话;用消息队列或者邮箱进行通信则可达到既 拨通别人的手机又与之通话的效果。换句话说,消息队列和邮箱可以及时传送事件的内容。
邮箱通信的机理:
发送方通过内核服务把一封邮件投递到邮箱,内核完成投递任务后通知等待列表中的接收方收取邮件。在整个投递过程中,内核充当了邮递员的角色。这里的“邮件”通常是一个指针,接收方可以通过该指针获取邮件内容。
邮箱的基本操作:
内核通常提供如下的邮箱服务:初始化邮箱的内容。邮箱最初可以包含或者不包含邮件。把邮件发送到邮箱(post)。如果邮箱已满,则返回错误信息
(OS_MBOX_FULL)。以“挂起”方式接收邮件(pend)。如果邮箱为空,则把取信者挂起;若超过一定时间邮箱仍为空,则返回超时信息。
以“非挂起”方式接收邮件(accept)。如果邮箱为空,则返回一个空指针。 当希望一次性向某个任务发送多则消息时,邮箱就有点见肘了。因为一个邮箱只能装一封信。把多上邮箱集中到一起管理和使用就变成了消息队列,所以消息队列的操作和邮箱很相似。可以简单地认为,消息队列是邮箱数组。 如果发送者是一对一的方式发送邮件,则等待列表中的优先级最高的任务将获取邮件;如果是以广播的方式发送邮件,则等待该邮件的所有任务将获得此邮件.
消息队列使用步骤:
1.建立一个指向消息数组的指针和数组的大小,该指针数组必须申明为void类型,如下:
void *MessageStorage[size]
2. 声明一个OS_EVENT类型的指针指向生成的队列,如下:
OS_EVENT *QSem;
3.OSQcreate()函数创建消息队列,如下:
QSem = OSQcreate(&MyArrayOfMsg[0],SIZE);
4.等待消息队列中的消息,OSQPend()
5. 向队列发送一条消息(FIFO),OSQPost();
6.1 向队列发送一条消息(LIFO),OSQPostFront()
6.2 向消息队列发送一则消息(LIFO或者FIFO)
INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
7、 无等待的从消息队列中获得消息,OSQAccept()
8、 清空消息队列 INT8U OSQFlush (OS_EVENT *pevent)
9、 获取消息队列的状态,OSQQuery()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)