RT-Thread 线程间通信 消息队列(2)

本文详细介绍了如何在系统中创建、初始化消息队列,以及发送和接收消息的函数机制,包括超时处理和线程调度。
摘要由CSDN通过智能技术生成

知道了消息队列的原理,创建消息队列搭建了一个什么东西,就好理解其他几个操作的函数的含义了。

1、消息队列的创建:

rt_mq_t rt_mq_create(const char * name,    //消息队列的名称
                    rt_size_t msg_size,    //消息队列中一条消息的最大长度,单位字节 
                    rt_size_t max_msgs,    //消息队列的最大个数 
                    rt_uint8_t flag)       //消息队列采用的等待方式
                                           //可以取值:RT_IPC_FLAG_FIFO
                                           //       或RT_IPC_FLAG_PRIO

创建消息队列,根据给的几个参数,创建一个空闲的消息队列,组成消息块链表,

内存的大小= [消息大小+消息头(用于链表连接)] *消息队列最大个数

返回消息队列的句柄

rt_err_t rt_mq_init(rt_mq_t     mq,        //消息队列句柄
                    const char *name,      //消息队列名称
                    void       *msgpool,   //存放消息队列区域的地址的指针
                    rt_size_t   msg_size,  //消息队列中一条消息的最大长度,单位字节 
                    rt_size_t   pool_size, //存放消息的缓冲区大小 
                    rt_uint8_t  flag)      //消息队列采用的等待方式
                                           //可以取值:RT_IPC_FLAG_FIFO
                                           //       或RT_IPC_FLAG_PRIO

2、消息队列的删除

rt_err_t rt_mq_detach(rt_mq_t mq)

rt_err_t rt_mq_delete(rt_mq_t mq)

使用该函数接口后,

内核先唤醒所有挂在该消息等待队列对象上的线程(返回值是 - RT_ERROR ),

然后将该消息队列对象从内核对象管理器中删除。

rt_mq_delete在删除前会把消息队列的内存释放掉再删除。

3、发送消息进入消息队列

rt_err_t rt_mq_send_wait(rt_mq_t     mq,        //mq是指向要发送的消息队列对象的指针
                         const void *buffer,    //buffer是消息的内容
                         rt_size_t   size,      //消息的长度(单位:字节)
                         rt_int32_t  timeout)   //timeout为超时时间,单位为系统的tick

发送消息进入消息队列会进行这些判断

判断消息队列是否为空?

        -->空:写入成功

        -->不空:-->返回失败

                       -->等待一段时间:-->另一个线程读的时候,唤醒陷入等待的线程

                                                     -->等待超时,返回失败

当线程选择等待一段时间的时候,会做一下几步操作:

1、会先把自己从系统的readylist里面移除,不在系统的待运行的线程列表里面了。

2、将自己放进mq->parent->suspend_thread 里面,

3、启动线程自己的定时器

当线程等待过程中,有其他线程把数据从消息队列里面读走,会唤醒mq->parent->suspend_thread 里面的线程,这时候这个线程就会再次启动。

若一直没其他线程唤醒,超时之后,线程会把自己的状态修改为TIMEOUT(也许实际不这么写),返回

其他两个发送消息的函数:

rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)

rt_mq_send( ) 其实就是timeout为0的 rt_mq_send_wait( )

rt_mq_urgent( ) 和普通的发送函数的区别是,将最新的消息插入到消息队列的最头部,这样,下一个读队列的函数就会立刻获取到这个消息

4、从消息队列接收消息

rt_err_t rt_mq_recv(rt_mq_t    mq,         //mq是指向要发送的消息队列对象的指针
                    const void *buffer,    //buffer是消息的内容
                    rt_size_t   size,      //消息的长度(单位:字节)
                    rt_int32_t  timeout)   //timeout为超时时间,单位为系统的tick

接收消息进入消息队列会进行这些判断

判断消息队列是否为空?

        -->不空:读取成功

        -->空: -->返回失败

                     -->等待一段时间:-->另一个线程写的时候,唤醒陷入等待的线程

                                                   -->等待超时,返回失败

当线程选择等待一段时间的时候,会做一下几步操作:

1、会先把自己从系统的readylist里面移除,不在系统的待运行的线程列表里面了。

2、将自己放进mq->parent->suspend_thread 里面,

3、启动线程自己的定时器

当线程等待过程中,有其他线程把数据写入消息队列里,会唤醒mq->parent->suspend_thread 里面的线程,这时候这个线程就会再次启动。

若一直没其他线程唤醒,超时之后,线程会把自己的状态修改为TIMEOUT(也许实际不这么写),返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值