关于无锁队列,详细的介绍请参考陈硕先生的《无锁队列的实现》一文。然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨。

无锁队列有两种实现形式,分别是数组与链表。以数组实现的无锁队列,限定了基本node的数目,然没有ABA问题。以链表实现的无锁队列,在内存允许的情况下可以添加任意数目的node,然有ABA问题。如何取二者的优点而摒弃其各自的缺点呢?

如果要做到可以无限伸缩,那么这种无锁队列须采用链表实现,然如何解决ABA问题呢?

ABA问题的本质就是地址重用,即两个(或多个)访问者访问一个node,其中一个释放了这个node,此时os会回收这个node。然后另外一个访问者要新生成一个node时,os会把刚释放掉的那个node的内存空间分配给这个访问者。在这个过程中,如果我们不把释放掉的node还给os,是不是问题就解决了?

可保存需要释放的node而不还给os的技术,我能想到的是内存池。一个以链表形式实现的无锁队列使用它的内存池时,如果要对这个内存池加锁,那就不是无锁队列了。

这个内存池中每个node大小一致,用一个数组形式的无锁队列实现即可。本文需要的无锁队列便是用列表实现的,而且基于数组无锁队列内存池。

这里面还有一个问题。还是上面的那个场景,node被访问者释放后,此时由内存池保存着,然后另一个访问者要申请一个node的内存空间,便会向内存池申请,如果内存池是把那个刚被释放掉的node空间分配给它呢?相当于内存池替代了os,问题依然没有解决。

既然内存空间现在由内存池而非os管理着,哪我们就可以想办法解决了。

还是上面那个场景,如果内存池中有很多个node,队列形式的内存池还会把刚被释放掉的node空间分配出去吗?所以需要在内存池中保存多个node。但保存多少合适呢?保存的node数量大于等于同时向内存池申请node空间的访问者即可。

node的数量取决于访问者的数目,若访问者是线程,则这个数目就是就是写线程的数目,这个参数可以让使用者设置。为了编程方便,我假设线程池线程写线程最多不会超过2048个,这个值应该大于当前多数服务器中CPU数量。

我在64位linux上用C实现了本文讨论的无锁队列。请点击这里下载地址,还是老规矩,零分下载。

欢迎批评指正。

此记。

一个可无限伸缩且无ABA问题的无锁队列的更多相关文章

  1. 无锁队列以及ABA问题

    队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...

  2. 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序

    分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图.      1.首先建立一个数 ...

  3. readerwriterqueue 一个用 C++ 实现的快速无锁队列

    https://www.oschina.net/translate/a-fast-lock-free-queue-for-cpp?cmp&p=2 A single-producer, sing ...

  4. boost 无锁队列

    一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...

  5. CAS简介和无锁队列的实现

    Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...

  6. 锁、CAS操作和无锁队列的实现

    https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...

  7. zeromq源码分析笔记之无锁队列ypipe_t(3)

    在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...

  8. 无锁队列--基于linuxkfifo实现

    一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...

  9. Go语言无锁队列组件的实现 (chan/interface/select)

    1. 背景 go代码中要实现异步很简单,go funcName(). 但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用"协程池 + 无锁队列"实现. 2. golang ...

随机推荐

  1. .Net中String和StringBuilder的区别

    String对象是不可变的而StringBuilder则不是这样,可以方便的Append进行扩展. 比如:string aa="123456",那么aa就会在内存中占用一块能放下这 ...

  2. 本地拦截genymotion或者Android模拟器的网络请求

    我们在主机上面运行了Burp或者fiddler,那么代理已经监听在本机的8080端口了. 那么我们需要在模拟器中进行如下设置: 1.在设置中,长按当前连接的wifi网络,弹出如下: 2. 点击修改网络 ...

  3. 使用 Node.js 做 Function Test

    Info 上周 meeting 上同事说他们现在在用 java 写 function test,产生了很多冗余的代码,整个项目也变得比较臃肿.现在迫切需要个简单的模板项目能快速搭建function t ...

  4. API之IP地址查询---权威的IP地址查询接口集合

    原文地址:http://yushine.iteye.com/blog/1717586 推荐实用IP138 http://www.baidu.com/s?wd=IP&rsv_spt=1& ...

  5. Jquery html页面处理基础

    1.怎样获得浏览器的可视高度?   var windHight = $(window).height(); //获得浏览器的可视高度 2.怎样获得滚动条相对于顶部的高度?   var scrollHi ...

  6. aix6.1 openssh安装

    环境: IBM AIX6.1 1.下载(可以直接从附件中下载): openssl IBM官方网站下载:https://www14.software.ibm.com/webapp/iwm/web/reg ...

  7. php获取服务器地址

    if ( isset( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) { // Support ProxyPass        $t_hosts = explode( ...

  8. T-SQL流程控制

    常用的T-SQL流程控制有三种,case ... when ... then...(else)...end (as) ... 判断句式,if判断句式和while循环句式. case...when .. ...

  9. css3设置box-pack和box-align让div里面的元素垂直居中

    只要设置元素的box-pack和box-align即可,这两个属性当前只有webkit和moz支持,要设置垂直居中的话只需要将这两个属性的值都设置为center即可,需要的朋友可以参考下   以前处理 ...

  10. bootstrap注意事项(四)表格

    1.基本实例 为任意 <table> 标签添加 .table 类可以为其赋予基本的样式 — 少量的内补(padding)和水平方向的分隔线.这种方式看起来很多余!?但是我们觉得,表格元素使 ...