邮箱和消息队列的机制非常相似,
可以理解为有线程向邮箱队列里面写数据,然后有线程从邮箱队列读数据
邮箱和消息队列的区别:
1、邮箱内存放的数据的大小是固定的,长度为unsigned long
消息队列里的数据的大小是创建消息队列的时候指定的,长度由msg_size确定
2、消息队列是一个队列,邮箱是环形队列。
3、消息队列使用指针来访问每个信息,
邮箱内部没有使用指针,内部各个消息长度是固定的,可以直接通过数组来访问每个信息
邮箱创建的时候,会划出一片空间,作为邮箱的数组,
邮箱的句柄:
struct rt_mailbox
{
struct rt_ipc_object parent; /**< inherit from ipc_object */
rt_ubase_t *msg_pool; /**< start address of message buffer */
rt_uint16_t size; /**< size of message pool */
rt_uint16_t entry; /**< index of messages in msg_pool */
rt_uint16_t in_offset; /**< input offset of the message buffer */
rt_uint16_t out_offset; /**< output offset of the message buffer */
rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */
};
typedef struct rt_mailbox *rt_mailbox_t;
邮箱的大小:
mb->msg_pool = (rt_ubase_t *)RT_KERNEL_MALLOC(mb->size * sizeof(rt_ubase_t));
三个值:
rt_uint16_t entry; /**邮箱中可以用的数据的个数*/
rt_uint16_t in_offset; /**邮箱环形队列的第一个值得位置*/
rt_uint16_t out_offset; /**邮箱环形队列的最后一个值得位置*/
在对邮箱进行写和读的时候会有以下判断:
读取邮箱内的数据:
-->邮箱内有数据:成功
-->邮箱内没数据:等待?
-->不等待:返回失败
-->等待: -->线程进入阻塞,把自己记录在邮箱的链表里面
-->超时退出
再次运行:需要写邮箱的线程唤醒,然后读取写进去的数值
写邮箱:
-->:有空位:成功
-->:没有空位:等待?
-->:不等待:返回失败
-->:等待:-->线程进入阻塞,把自己记录在邮箱的链表里面
-->超时退出
再次运行:需要读邮箱的线程唤醒,然后写进去数值。