1. data_queue 是什么
data_queue 直接翻译过来是 数据队列。这个名字和 消息队列 很像。那么他们有什么区别呢?
消息队列:消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。其他线程也能够从消息队列中读取相应的消息,而当消息队列是空的时候,可以挂起读取线程。当有新的消息到达时,挂起的线程将被唤醒以接收并处理消息。消息队列是一种异步的通信方式。
数据队列:没有找到官方详细的说明,数据队列能够接收来自线程中不固定长度的数据,数据 不会 缓存在自己的内存空间中,自己的内存空间只有一个指向这包数据的指针。其他线程也能够从数据队列获取数据,当数据队列为空的时候,可以挂起线程。当有新的数据到达时,挂起的线程将被唤醒以接收并处理消息。数据队列是一种异步的通信方式。
消息队列 是用于线程消息传递的,属于线程间同步异步 IPC;消息队列在 recv 数据之后,这组数据就没了。
数据队列 更多的使用在流式数据传递,属于线程间通信 IPC;数据队列可以使用 peak 的方式 舔一下 这组数据不会丢失。自带高、低水位,可以对锯齿速度(压入数据的间隔不一致,时快时慢的)情况进行调节。
2. data_queue 怎么使用
data_queue 的 API 很少,使用起来也非常简单。
##### 1. 定义一个数据队列
##### 2. 初始化数据队列
struct rt_data_queue : 数据队列控制块
size : 数据队列的容量
lwm : 数据队列的阈值
(evt_notify)(struct rt_data_queue queue, rt_uint32_t event): 通知回调函数
##### 3. 反初始化数据队列
##### 4. 往数据队列压入数据
const void *data_ptr : 保存数据的指针
data_size : 数据的大小
5. 从数据队列弹出数据
data_ptr : 指向了保存数据的地址
size : 收到数据的大小
6. 取出但保留数据队列中的数据
data_ptr : 指向了保存数据的地址
size : 收到数据的大小
7. 重置数据队列
3. data_queue 的实现
1. 初始化数据队列
伪代码:
给 struct rt_data_queue 的成员赋值:
evt_notify : 事件通知回调函数
size : 数据队列的容量
lwm : 数据队列的阈值
magic :数据队列的魔法字
get_index :获取数据的下标
put_index :压入数据的下标
suspended_push_list :压入数据的挂起线程的链表
suspended_pop_list :弹出数据的挂起线程的链表
2. 反初始化数据队列
伪代码:
释放 data_queue 申请的内存。
3. 向数据队列中写入数据
伪代码:
4. 取出数据队列中的数据
伪代码 :
5. 取出但保留数据队列中的数据
注意 : 这里没有移动 queue->get_index += 1; 所以数据没有被取走,下次读还是在这里。这也就是 pop 和 peak 的区别。
6. 重置数据队列
伪代码:
4. 最后
标准版 RT-Thread 中的 rt_data_queue 源码在 " t-threadcomponentsdriverssrcdataqueue.c"在你要使用的文件中#include dataqueue.h直接就可以使用。
Nano 版 RT-Thread 直接拷贝 dataqueue.c 和 dataqueue 添加到工程就可以使用。
rt_data_queue 不是 从 rt_object 派生出来的。 rt_data_queue 运用于流数据的特定场景。
|