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 数据结构
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 函数列表:
2. ring queue 数据结构
r_cursor 读指针,只在线程B中才能被修改,对于线程A,它是readonly的 w_cursor 写指针,只在线程A中才能被修改,对于线程B,它是readonly的 length 缓冲区长度 data 缓冲区实体 与ring buffer,在data中,同样需要保留1byte的位置,原理与ring buffer相似,只是tw_cursor,tw_cursor 用临时变量代替而已。 函数列表:
|
|
来自: goodwangLib > 《数据结构》