环形缓冲区(ring buffer),环形队列(ring queue) 原理
来源:互联网 发布:淘宝购物返利机器人 编辑:程序博客网 时间:2024/05/21 21:35
1. 序言
环形缓冲区(ring buffer),环形队列(ring queue) 多用于2个线程之间传递数据,是标准的先入先出(FIFO)模型。一般来说,对于多线程共享数据,需要使用mutex来同步,这样共享数据才不至于发生不可预测的修改/读取,然而,mutex的使用也带来了额外的系统开销,ring buffer/queue 的引入,就是为了有效地解决这个问题,因其特殊的结构及算法,可以用于2个线程中共享数据的同步,而且必须遵循A线程push in,B线程pull out的原则。采用这个机制另外一个用处是A push完数据后可以马上接收另外一个数据,当输入数据快速时不容易造成数据阻塞而丢包.
线程 A 媒介 线程 B
data in --> ring buffer/queue --> data out
2. ring buffer 数据结构
ring buffer主要用于存储一段连续的数据块,例如网络接收的数据。
r_cursor 读指针,只在线程B中才能被修改,对于线程A,它是readonly的
tr_cursor 辅助读指针,只在线程B中才能被引用,用于计算当前有多少可读数据
w_cursor 写指针,只在线程A中才能被修改,对于线程B,它是readonly的
tw_cursor 辅助写指针,只在线程A中才能被引用,用于计算当前有多少空闲位置可以写入数据
length 缓冲区长度
data 缓冲区实体
需要注意的是,在data中,需要保留1byte的位置,因为:
具体原理可参考 IDirectSoundBuffer8
函数列表:
2. ring queue 数据结构
ring buffer主要用于存储指针,这个指针指向共享数据的entry.
r_cursor 读指针,只在线程B中才能被修改,对于线程A,它是readonly的
w_cursor 写指针,只在线程A中才能被修改,对于线程B,它是readonly的
length 缓冲区长度
data 缓冲区实体
与ring buffer,在data中,同样需要保留1byte的位置,原理与ring buffer相似,只是tw_cursor,tw_cursor
用临时变量代替而已。
函数列表:
环形缓冲区(ring buffer),环形队列(ring queue) 多用于2个线程之间传递数据,是标准的先入先出(FIFO)模型。一般来说,对于多线程共享数据,需要使用mutex来同步,这样共享数据才不至于发生不可预测的修改/读取,然而,mutex的使用也带来了额外的系统开销,ring buffer/queue 的引入,就是为了有效地解决这个问题,因其特殊的结构及算法,可以用于2个线程中共享数据的同步,而且必须遵循A线程push in,B线程pull out的原则。采用这个机制另外一个用处是A push完数据后可以马上接收另外一个数据,当输入数据快速时不容易造成数据阻塞而丢包.
线程 A 媒介 线程 B
data in --> ring buffer/queue --> data out
2. ring buffer 数据结构
- struct _RingB
- {
- SI32 r_cursor;
- SI32 w_cursor;
- SI32 tr_cursor;
- SI32 tw_cursor;
- SI32 length;
- char data[0];
- };
r_cursor 读指针,只在线程B中才能被修改,对于线程A,它是readonly的
tr_cursor 辅助读指针,只在线程B中才能被引用,用于计算当前有多少可读数据
w_cursor 写指针,只在线程A中才能被修改,对于线程B,它是readonly的
tw_cursor 辅助写指针,只在线程A中才能被引用,用于计算当前有多少空闲位置可以写入数据
length 缓冲区长度
data 缓冲区实体
需要注意的是,在data中,需要保留1byte的位置,因为:
a...
push数据时,理论上来说,我们应该是从 thiz->tw_cursor = (thiz->w_cursor + 1) % thiz->length;
开始写的,如果此时 thiz->tw_cursor == thiz->r_cursor, 我们认为此时缓冲区已满b...
pull数据时,也是相同的道理,thiz->r_cursor == thiz->w_cursor,我们认为此时缓冲区无数据可读
也就是说,r_cursor == w_cursor 是一个特殊的位置,所以我们需要在data里面保留1byte。具体原理可参考 IDirectSoundBuffer8
函数列表:
- RingB* ringb_create(UI32 size);
- void ringb_destroy(RingB* thiz);
- SI32 ringb_write_lock(RingB* thiz, SI8** ptr1, SI32* size1, SI8** ptr2, SI32* size2);
- SI32 ringb_write_unlock(RingB* thiz, const SI8* ptr1, SI32 size1, const SI8* ptr2, SI32 size2);
- SI32 ringb_write(SI8* ptr1, SI32* size1, SI8* ptr2, SI32* size2, const SI8* src, SI32 len);
- SI32 ringb_read_lock(RingB* thiz, SI8** ptr1, SI32* size1, SI8** ptr2, SI32* size2);
- SI32 ringb_read_unlock(RingB* thiz, const SI8* ptr1, SI32 size1, const SI8* ptr2, SI32 size2);
- SI32 ringb_read(const SI8* ptr1, SI32* size1,const SI8* ptr2, SI32* size2, SI8* dst, SI32 len);
2. ring queue 数据结构
- struct _RingQ
- {
- SI32 r_cursor;
- SI32 w_cursor;
- SI32 length;
- void* data[0];
- };
r_cursor 读指针,只在线程B中才能被修改,对于线程A,它是readonly的
w_cursor 写指针,只在线程A中才能被修改,对于线程B,它是readonly的
length 缓冲区长度
data 缓冲区实体
与ring buffer,在data中,同样需要保留1byte的位置,原理与ring buffer相似,只是tw_cursor,tw_cursor
用临时变量代替而已。
函数列表:
- RingQ* ringq_create(SI32 size);
- void ringq_destroy(RingQ* thiz);
- SI32 ringq_push(RingQ* thiz, void* data);
- SI32 ringq_pop(RingQ* thiz, void** data);
- SI32 ringq_fakePop(RingQ* thiz, void** data);
- SI32 ringq_tryPush(RingQ* thiz);
- SI32 ringq_tryPop(RingQ* thiz);
1 0
- 环形缓冲区(ring buffer),环形队列(ring queue) 原理
- 环形缓冲区(ring buffer),环形队列(ring queue) 原理
- Ring Buffer (circular Buffer)环形缓冲区简介
- Ring Buffer (circular Buffer)环形缓冲区
- Ring Buffer (circular Buffer)环形缓冲区简介
- (转载)环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- (转载)环形缓冲区的实现原理(ring buffer) .
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- Ring Buffer (circular Buffer)环形缓冲区简介(C++版本)
- 环形缓冲器 circular buffer, ring buffer
- Ring buffer basics 环形缓冲基础 一
- servlet笔记
- linux 下man的用法
- RxJava练习(1)--timer代替Handler
- bitnami 版 gitlab 修改端口
- 20.给UITextField添加一些小动画, 增强UI界面的趣味
- 环形缓冲区(ring buffer),环形队列(ring queue) 原理
- POJ1046 Color Me Less 水题
- 《转》基于OpenCV的傅里叶变换及逆变换
- MaterialDesign 之 NavigationView
- eclipse+maven+Hibernate创建JavaWeb项目
- java多文件打包下载
- lucene
- Android 应用程序常用工具类及功能包
- 从Eclipse+ADT迁移到Android Studio