架构设计:生产者/消费者模式 第6页:环形缓冲区的实现

架构设计:生产者/消费者模式 第6页:环形缓冲区的实现

◇判断“空”和“满”java

    上述的操做并不复杂,不过有一个小小的麻烦:空环和满环的时候,R和W都指向同一个位置!这样就没法判断究竟是“空”仍是“满”。大致上有两种方法能够解决该问题。程序员

    办法1:始终保持一个元素不用编程

    当空环的时候,R和W重叠。当W比R跑得快,追到距离R还有一个元素间隔的时候,就认为环已经满。当环内元素占用的存储空间较大的时候,这种办法显得很土(浪费空间)。数组

    办法2:维护额外变量安全

    若是不喜欢上述办法,还能够采用额外的变量来解决。好比能够用一个整数记录当前环中已经保存的元素个数(该整数>=0)。当R和W重叠的时候,经过该变量就能够知道是“空”仍是“满”。架构

    ◇元素的存储并发

    因为环形缓冲区自己就是要下降存储空间分配的开销,所以缓冲区中元素的类型要选好。尽可能存储值类型的数据,而不要存储指针(引用)类型的数据。由于指针类型的数据又会引发存储空间(好比堆内存)的分配和释放,使得环形缓冲区的效果打折扣。编程语言

    ★应用场合性能

    刚才介绍了环形缓冲区内部的实现机制。按照前一个帖子的惯例,咱们来介绍一下在线程和进程方式下的使用。spa

    若是你所使用的编程语言和开发库中带有现成的、成熟的环形缓冲区,强烈建议使用现成的库,不要从新制造轮子;确实找不到现成的,才考虑本身实现。若是你纯粹是业余时间练练手,那另当别论。

    ◇用于并发线程

    和线程中的队列缓冲区相似,线程中的环形缓冲区也要考虑线程安全的问题。除非你使用的环形缓冲区的库已经帮你实现了线程安全,不然你仍是得本身动手搞定。线程方式下的环形缓冲区用得比较多,相关的网上资料也多,下面就大体介绍几个。

    对于C++的程序员,强烈推荐使用boost提供的circular_buffer模板,该模板最开始是在boost 1.35版本中引入的。鉴于boost在C++社区中的地位,大伙儿应该能够放心使用该模板。

    对于C程序员,能够去看看开源项目circbuf,不过该项目是GPL协议的,不太爽;并且活跃度不过高;并且只有一个开发人员。大伙儿慎用!建议只拿它当参考。

    对于C#程序员,能够参考CodeProject上的一个示例。

    ◇用于并发进程

    进程间的环形缓冲区,彷佛少有现成的库可用。大伙儿只好本身动手、丰衣足食了。

    适用于进程间环形缓冲的IPC类型,常见的有共享内存和文件。在这两种方式上进行环形缓冲,一般都采用数组的方式实现。程序事先分配好一个固定长度的存储空间,而后具体的读写操做、判断“空”和“满”、元素存储等细节就可参照前面所说的来进行。

    共享内存方式的性能很好,适用于数据流量很大的场景。可是有些语言(好比Java)对于共享内存不支持。所以,该方式在多语言协同开发的系统中,会有必定的局限性。

    而文件方式在编程语言方面支持很好,几乎全部编程语言都支持操做文件。但它可能会受限于磁盘读写(Disk I/O)的性能。因此文件方式不太适合于快速数据传输;可是对于某些“数据单元”很大的场合,文件方式是值得考虑的。

    对于进程间的环形缓冲区,一样要考虑好进程间的同步、互斥等问题,限于篇幅,此处就不细说了。

相关文章
相关标签/搜索