- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
环形缓冲区的扩展方法
环形缓冲区的扩展方法
摘 要 环形缓冲区是一种高效的数据缓存结构,在多线程异步协作或者分级操作的生产者消费者模式中被广泛使用。它的容量通常是固定不变的,在缓冲区满的时候会有数据丢失或者数据覆盖的问题。本文提出了对环形缓冲区进行扩展的两种方法,并实验论证了两种扩展方法的有效性。
【关键词】环形缓冲区 阶梯式扩展法 链式扩展法
1 环形缓冲区简介
环形缓冲区(ring buffer, circular buffer, cyclic buffer)是一种数据结构,它的大小通常是固定不变的,存储空间在逻辑上首尾相连,如图1所示。环形缓冲区中存储的数据遵循先进先出(FIFO)的规则,通常也称之为环形队列。
1.1 环形缓冲区的实现原理
环形缓冲区的大小(S)通常是固定不变的,有一个读指针(R)和一个写指针(W),R指向环形缓冲区中当前可读数据的位置,W指向环形缓冲区中当前的可写位置。初始状态R和W指向同一位置,环形缓冲区中存储的数据个数(N)初始为0,如图2所示,此时环形缓冲区为空。
每写入一个数据,则N+1,同时移动W指向下一个可写位置。图3是写入3个数据D1, D2和D3之后的环形缓冲区状态。
每读出一个数据,则N-1,同时移动R指向下一个可读数据的位置。图4是读出2个数据D1和 D2之后的环形缓冲区状态。
当写入数据个数N等于S时,环形缓冲区满,此时读写指针R和W指向同一位置,如图5所示。
1.2 环形缓冲区的特点
环形缓冲区的一个重要特点就是读写数据的时候不用进行内存的分配和释放操作(频繁的内存分配和释放操作容易造成内存碎片,从而降低系统性能),只需要在读/写数据之后,相应的移动R/W指针即可。
在多线程异步协作或者分级操作的过程中,环形缓冲区的高性能可以提高整个系统的并发性和吞吐量。
2 环形缓冲区存在的问题
环形缓冲区存在的问题就是它的容量是固定不变的,即最多能够存储的数据量(通常在初始化阶段设定)是固定不变的。在环形缓冲区满的情况下,新数据或者被丢弃,或者覆盖旧数据,或者写线程挂起,等待环形缓冲区进入可写状态。
例如, C++ Boost库的环形缓冲区实现(boost::circular_buffer)在环形缓冲区满的情况下,新数据就会覆盖旧数据,从而造成数据的丢失。
要解决这个问题,就需要对环形缓冲区进行扩展,使它的容量可变,在系统内存允许的范围内扩大存储量。
3 环形缓冲区的扩展方法
通常有两种方法对环形缓冲区进行扩展,第一种方法可以称之为阶梯式扩展法,第二种方法可以称之为链式扩展法。
3.1 阶梯式扩展法
阶梯式扩展法的实现原理:在环形缓冲区满的时候,向系统申请分配一块更大的内存,
并将原有缓冲区内的数据复制到新的内存区,释放原有缓冲区资源,使用新的更大的内存区作为环形缓冲区,以满足数据量增长的需求。
阶梯式扩展法的特点是可以使环形缓冲区的容量随着数据量的增长而呈阶梯式增大。但是在扩展的过程中存在着数据复制的开销,会在一定程度上影响系统的性能。
一个典型的例子,就是基于数组的队列实现(ArrayQueue)。
以图5为例,此时环形缓冲区已满,新数据D11的写入主要分为以下步骤:
1.申请分配一块更大的内存,假设增量大小为5,则内存大小S = 7+5 = 12。
2.从读指针R开始,将原有数据复制到新的内存区,并调整读指针R和写指针W到新的位置。释放原有缓冲区资源。
3.写入新数据D11,移动写指针W至下一位置,N+1。
3.2 链式扩展法
链式扩展法的实现原理:保留使用原有的缓冲区,在环形缓冲区满的时候,向系统申请分配另外一块内存并将它和原有的缓冲区链接起来,共同作为新的环形缓冲区。
链式扩展法相对阶梯式扩展法的优势是避免了数据复制的开销,但是链式扩展法读写指针的移动相对复杂一点,下一个可读或者可写的位置与缓冲区的扩展点(即新申请的内存和原有缓冲区的链接点)密切相关。
还是以图5为例,此时环形缓冲区已满,新数据D11的写入主要分为以下步骤:
(1)申请分配一块增量内存,假设增量大小为5,则总内存大小S = 7+5 = 12。
(2)将原有缓冲区的扩展点和新申请的内存区链接起来,并调整写指针W到新的可写位置。
(3)写入新数据D11,移动写指针W至下一位置,N+1。
3.3 注意事项
经过编码测试,实验结果证明了阶梯式扩展法和链式扩展法都是行之有效的。 需要注意的几个事项,如下所列:
(1)环形缓冲区的可扩展最大容量不可操过系统的允许范围。
(2)极端情况下,如持续的进行写操作导致环形缓冲区达到可
文档评论(0)