1、消息队列概念:
队列又称消息队列,是一种常用于线程间通信的数据结构,队列可以在线程与线程间、中断和线 程间传送信息,实现了线程接收来自其他线程或中断的不固定长度的消息,并根据不同的接口选 择传递消息是否存放在线程自己的空间。线程能够从队列里面读取消息,当队列中的消息是空 时,挂起读取线程,用户还可以指定挂起的线程时间 ti meout;当队列中有新消息时,挂起的读 取线程被唤醒并处理新消息,消息队列是一种异步的通信方式。
2、消息队列的运作机制:
队列的运作过程具体见队列读写数据操作示意图。
3、消息队列的阻塞机制:
先来后到的机制,为了保护每个线程对它进行读写操作的过程,我们必须要有 阻塞机制,在某个线程对它读写操作的时候,必须保证该线程能正常完成读写操作,而不受后来 的线程干扰。
4、消息队列的应用场景:
消息队列可以应用于发送不定长消息的场合,包括线程与线程间的消息交换,以及在中断服务函 数中给线程发送消息(中断服务例程不可能接收消息)。
5、消息队列控制块:
1 struct rt_messagequeue {
2 struct rt_ipc_object parent; //会在自身结构体里面包含一个内核对
象类型的成员,通过这个成员可以将消息队列挂到系统对象容器里面。
3
4 void *msg_pool; //存放消息的消息池开始地址
5
6 rt_uint16_t msg_size; //每条消息大小,消息队列中也就是节点的大小,单位为字节
7 rt_uint16_t max_msgs; //能够容纳的最大消息数量
8
9 rt_uint16_t entry; //队列中的消息索引,记录消息队列的消息个数
10
11 void *msg_queue_head; //链表头指针,指向即将读取数据的节点
12 void *msg_queue_tail; //链表尾指针,指向允许写入数据的节点
13 void *msg_queue_free; //指向队列的空闲节点的指针
14 };
15 typedef struct rt_messagequeue *rt_mq_t;
6、常用消息队列函数:
• 创建消息队列 rt_mq_create()
1 /* 创建一个消息队列 */
2 test_mq = rt_mq_create("test_mq", /* 消息队列名字 */
3 40, /* 消息的最大长度 */
4 20, /* 消息队列的最大容量 */
5 RT_IPC_FLAG_FIFO);/* 队列模式 FIFO(0x00)*/
6 if (test_mq != RT_NULL)
7 rt_kprintf("消息队列创建成功!\n\n");
• 写队列操作函数 rt_mq_send()
• 读队列操作函数 rt_mq_recv()
1 /* 队列读取(接收),等待时间为一直等待 */
2 uwRet = rt_mq_recv(test_mq, /* 读取(接收)队列的 ID(句柄) */
3 &r_queue, /* 读取(接收)的数据保存位置 */
4 sizeof(r_queue), /* 读取(接收)的数据的长度 */
5 RT_WAITING_FOREVER); /* 等待时间:一直等 */
6 if (RT_EOK == uwRet)
7 {
8 rt_kprintf("本次接收到的数据是:%d\n",r_queue);
9 } else
10 {
11 rt_kprintf("数据接收出错, 错误代码: 0x%lx\n",uwRet);
12 }
• 删除队列 rt_mq_delete()