一个可无限伸缩且无ABA问题的无锁队列
关于无锁队列,详细的介绍请参考陈硕先生的《无锁队列的实现》一文。然进一步,如何实现一个不限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问题的无锁队列的更多相关文章
- 无锁队列以及ABA问题
队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...
- 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序
分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图. 1.首先建立一个数 ...
- readerwriterqueue 一个用 C++ 实现的快速无锁队列
https://www.oschina.net/translate/a-fast-lock-free-queue-for-cpp?cmp&p=2 A single-producer, sing ...
- boost 无锁队列
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...
- CAS简介和无锁队列的实现
Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...
- 锁、CAS操作和无锁队列的实现
https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...
- zeromq源码分析笔记之无锁队列ypipe_t(3)
在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...
- 无锁队列--基于linuxkfifo实现
一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...
- Go语言无锁队列组件的实现 (chan/interface/select)
1. 背景 go代码中要实现异步很简单,go funcName(). 但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用"协程池 + 无锁队列"实现. 2. golang ...
随机推荐
- .Net中String和StringBuilder的区别
String对象是不可变的而StringBuilder则不是这样,可以方便的Append进行扩展. 比如:string aa="123456",那么aa就会在内存中占用一块能放下这 ...
- 本地拦截genymotion或者Android模拟器的网络请求
我们在主机上面运行了Burp或者fiddler,那么代理已经监听在本机的8080端口了. 那么我们需要在模拟器中进行如下设置: 1.在设置中,长按当前连接的wifi网络,弹出如下: 2. 点击修改网络 ...
- 使用 Node.js 做 Function Test
Info 上周 meeting 上同事说他们现在在用 java 写 function test,产生了很多冗余的代码,整个项目也变得比较臃肿.现在迫切需要个简单的模板项目能快速搭建function t ...
- API之IP地址查询---权威的IP地址查询接口集合
原文地址:http://yushine.iteye.com/blog/1717586 推荐实用IP138 http://www.baidu.com/s?wd=IP&rsv_spt=1& ...
- Jquery html页面处理基础
1.怎样获得浏览器的可视高度? var windHight = $(window).height(); //获得浏览器的可视高度 2.怎样获得滚动条相对于顶部的高度? var scrollHi ...
- aix6.1 openssh安装
环境: IBM AIX6.1 1.下载(可以直接从附件中下载): openssl IBM官方网站下载:https://www14.software.ibm.com/webapp/iwm/web/reg ...
- php获取服务器地址
if ( isset( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) { // Support ProxyPass $t_hosts = explode( ...
- T-SQL流程控制
常用的T-SQL流程控制有三种,case ... when ... then...(else)...end (as) ... 判断句式,if判断句式和while循环句式. case...when .. ...
- css3设置box-pack和box-align让div里面的元素垂直居中
只要设置元素的box-pack和box-align即可,这两个属性当前只有webkit和moz支持,要设置垂直居中的话只需要将这两个属性的值都设置为center即可,需要的朋友可以参考下 以前处理 ...
- bootstrap注意事项(四)表格
1.基本实例 为任意 <table> 标签添加 .table 类可以为其赋予基本的样式 — 少量的内补(padding)和水平方向的分隔线.这种方式看起来很多余!?但是我们觉得,表格元素使 ...