RT-Thread消息队列(消息队列的概念和基础使用)
@TOC
前言
本篇文章将开始带大家学习RT-Thread中的消息队列,消息队列主要用于线程之间的通信。
一、消息队列的概念
在 RT-Thread 中,消息队列是一种用于线程间通信的机制,允许一个线程向另一个线程发送数据或者消息。消息队列通常被用于实现异步的、非阻塞的线程间通信。以下是消息队列的概念和基本用法:
概念:
消息队列:消息队列是一个先进先出(FIFO)的数据结构,用于在多线程环境下传递数据或消息。它可以存储多个消息,并且允许一个线程发送消息到队列的尾部,另一个线程从队列的头部接收消息。
消息:消息是一个数据单元,它可以是任意类型的数据,如整数、浮点数、结构体等。发送线程将消息发送到队列中,接收线程从队列中获取消息进行处理。
消息队列长度:消息队列通常有一个固定的最大长度,当队列已满时,发送线程可能会被阻塞,直到队列有足够的空间存放新消息。同样,当队列为空时,接收线程可能会被阻塞,直到队列中有新的消息可供获取。
二、消息队列函数
2.1消息队列的内部结构
消息队列头部:消息队列的头部通常包含元数据,例如队列的大小、当前消息数量等信息。这些元数据可以帮助管理和控制消息队列的操作。
数据链表:数据链表用于保存消息数据。每个节点通常包含一个消息块,消息块中存储着实际的消息数据。通过链表结构,可以方便地添加、删除和查找消息数据,实现消息的发送和接收。
空闲链表:空闲链表用于管理可用的消息块。每个节点代表一个空闲消息块,当需要发送消息时,可以从空闲链表中获取一个空闲消息块,并将消息数据复制到其中。发送完消息后,空闲消息块会重新加入空闲链表中,以便下次使用。
2.2创建消息队列函数
消息队列的创建有两种方法:动态分配内存、静态分配内存
动态分配内存:rt_mq_create,消息队列的内存在函数内部动态分配
静态分配内存:rt_mq_init,消息队列的内存要事先分配好
rt_mq_create 函数:
rt_mq_t rt_mq_create(const char* name, rt_size_t msg_size, rt_size_t max_msgs, rt_uint8_t flag);
参数:
name:消息队列的名称,用于标识消息队列。
msg_size:每个消息的大小,以字节为单位。
max_msgs:消息队列能容纳的最大消息数。
flag:消息队列的标志,可以是 RT_IPC_FLAG_FIFO(先进先出)或 RT_IPC_FLAG_PRIO(按优先级)。
返回值:
如果成功创建了消息队列,则返回一个消息队列对象的指针 (rt_mq_t)。
如果创建失败,则返回 RT_NULL。
rt_mq_init 函数:
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);
参数:
mq:消息队列对象的指针。
name:消息队列的名称,用于标识消息队列。
msgpool:用于存储消息的内存池的指针。
msg_size:每个消息的大小,以字节为单位。
pool_size:消息池的大小,即能容纳的消息数。
flag:消息队列的标志,可以是 RT_IPC_FLAG_FIFO(先进先出)或 RT_IPC_FLAG_PRIO(按优先级)。
返回值:
如果成功初始化了消息队列,则返回 RT_EOK。
如果初始化失败,则返回一个错误码,表示初始化失败的原因。
使用示例:
使用 rt_mq_create 创建消息队列:
#include <rtthread.h>
#define MSG_SIZE sizeof(int)
#define MAX_MSGS 5
void example_thread_entry(void *parameter) {
rt_mq_t queue = rt_mq_create("my_queue", MSG_SIZE, MAX_MSGS, RT_IPC_FLAG_FIFO);
if (queue == RT_NULL) {
rt_kprintf("Failed to create message queue!\n");
return;
}
// 使用消息队列...
}
使用 rt_mq_init 初始化消息队列对象:
#include <rtthread.h>
#define MSG_SIZE sizeof(int)
#define POOL_SIZE (MSG_SIZE * MAX_MSGS)
static rt_uint8_t msg_pool[POOL_SIZE];
static rt_mq_t queue;
void example_thread_entry(void *parameter) {
rt_err_t result = rt_mq_init(&queue, "my_queue", msg_pool, MSG_SIZE, MAX_MSGS, RT_IPC_FLAG_FIFO);
if (result != RT_EOK) {
rt_kprintf("Failed to initialize message queue! Error code: %d\n", result);
return;
}
// 使用消息队列...
}
在上述示例中,rt_mq_create 函数用于动态创建一个消息队列,并返回消息队列对象的指针。而 rt_mq_init 函数则用于初始化一个静态分配的消息队列对象,并传入预先分配的消息池。
2.3消息队列的删除
rt_err_t rt_mq_delete(rt_mq_t mq);
这个函数用于删除一个消息队列,并释放与之相关的资源。具体的参数和返回值如下:
参数:
mq:要删除的消息队列对象的指针。
返回值:
如果成功删除了消息队列,则返回 RT_EOK。
如果删除失败,则返回一个错误码,表示删除失败的原因。
rt_err_t rt_mq_detach(rt_mq_t mq);
这个函数用于分离一个消息队列,即不再使用它,但不释放相关资源。具体的参数和返回值如下:
参数:
mq:要分离的消息队列对象的指针。
返回值:
如果成功分离了消息队列,则返回 RT_EOK。
如果分离失败,则返回一个错误码,表示分离失败的原因。
#include <rtthread.h>
static rt_mq_t queue;
void example_thread_entry(void *parameter) {
// 初始化消息队列
queue = rt_mq_create("my_queue", sizeof(int), 5, RT_IPC_FLAG_FIFO);
if (queue == RT_NULL) {
rt_kprintf("Failed to create message queue!\n");
return;
}
// 使用消息队列...
// 删除消息队列
rt_err_t result_delete = rt_mq_delete(queue);
if (result_delete != RT_EOK) {
rt_kprintf("Failed to delete message queue! Error code: %d\n", result_delete);
return;
}
// 或者分离消息队列
rt_err_t result_detach = rt_mq_detach(queue);
if (result_detach != RT_EOK) {
rt_kprintf("Failed to detach message queue! Error code: %d\n", result_detach);
return;
}
}
2.4消息队列写数据函数
2.5消息队列读数据函数
总结
- 点赞
- 收藏
- 关注作者
评论(0)