C++无锁编程资料,无锁队列等

C++无锁编程资料,无锁队列等1.Lamport’sLock-FreeRingBuffer    [Lamport,Comm.ofACM,1977]   也就常说的单生产者-单消费者的ringbuffer,限制就是只能一个读线程(消费者),一个写进程(生产者)。    好像有人改进了一下设计,参加文章“Cache优化的并发无锁队列”http://www.doci

大家好,又见面了,我是你们的朋友全栈君。

1. Lamport’s Lock-Free Ring Buffer  

     [Lamport, Comm. of ACM, 1977]

     也就常说的单生产者-单消费者 的ringbuffer, 限制就是只能一个读线程(消费者),一个写进程(生产者)。  

     好像有人改进了一下设计, 参加文章 “Cache优化的并发无锁队列” http://www.docin.com/p-30332640.html  ,这论文里面 “Fastforward for efficient pipeline parallelism: A Cache-Optimized Concurrent Lock-Free Queue  ” 里面有说

 

. Lamport’s queue implementation

=================================

1 enqueue_nonblock(data) {

2 if (NEXT(head) == tail) {   同时访问 head和tail

3 return EWOULDBLOCK;

4 }

5 buffer[head] = data;

6 head = NEXT(head);

7 return 0;

8 }

1 dequeue_nonblock(data) {

2

3 if (head == tail) {        同时访问 head和tail

4 return EWOULDBLOCK;

5 }

6 data = buffer[tail];

7 tail = NEXT(tail);

8 return 0;

9 }

—————————–

FastForward queue implementation

==============================

1 enqueue_nonblock(data) {

2 if (NULL != buffer[head]) {              通过避免同时在 读写线程中访问head和tail两个变量来避免cache抖动的的更好的性能

3 return EWOULDBLOCK;

4 }

5 buffer[head] = data;

6 head = NEXT(head);

7 return 0;

8 }

1 dequeue_nonblock(data) {

2 data = buffer[tail];           只访问tail

3 if (NULL == data) {

4 return EWOULDBLOCK;

5 }

6 buffer[tail] = NULL;

7 tail = NEXT(tail);

8 return 0;

9 

 

 

 

2,  Michael &Scott 无锁队列    

     支持多个读线程(消费者)和多个写进程(生产者)同时工作

    “Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms”

     这里http://www.cs.rochester.edu/research/synchronization/pseudocode/queues.html  有伪码,

     有人按照这个用C++实现了,http://www.cnblogs.com/napoleon_liu/archive/2010/08/07/1794566.html

    

     其实就是在修改链表指针时,利用intel的CAS(compare and swap交换和赋值)原子指令来做具体的修改赋值。我记得linux内核代码看到比较多的是xchg系列,上面的那个blog利用的lock前缀的“”lock cmpxchg16b”指令,应该一样的道理。一般都是搞个while循环直到修改成功。

 

 

另有吕慧伟 缩写的“无锁编程简介An Intro to Lock-free  Programming”  http://www.tektalk.org/wp-content/uploads/2011/07/lock-free-intro1.pdf  给了一个简单的源代码

 

void enQ(request, queue)

{

    do{

        local_head = queue->head;

        request->next = queue->head;

        val = cmpxchg(&queue->head, 

        local_head, request);

    }while(val != local_head)

}

 

类似的可以利用CAS实现无锁堆栈 代码同样来自吕慧伟的文章

struct elem {

  elem *link

any data;

}

elem *qhead;

—————

Push (elem *x)

  do 

    old = qhead;

    x->link = old;

    new = x;

    cc = CAS(qhead, old, new);

  until (cc == old;

————–

Pop ()

  do 

    old = qhead;

    new = old->link;

    cc = CAS(qhead, old, new);

  until (cc == old;)

return old

—————–

 

另外需要的注意点是,文章提到如果不同的线程里面使用一个共享的元素来做插入和删除操作时是有非常严重的“ABA问题”的,会导致元素的丢失, CAS指令不能分辨这个元素是不是在本线程被中断之后,又已经被另外的线程取出(已经被消费了)再重新作为新的元素又被插入的情况,这是CAS就会导致多删了一个元素。这时就要引入个操作的序列号区来进行区分,解决问题。去看一下原文吧。

 

 

“钱立兵 陈波 晏涛 徐云 孟金涛 刘涛” 等人写的“多线程并发访问无锁队列的算法研究”  http://www.siat.ac.cn/xscbw/xsqk/200906/W020091127490148897561.pdf

提到一个 Edya Ladan-Mozes和 Nir Shavit 的optimistic算法算法,所示上面的  Michael &Scott方法的改进,可以通过 更少的CAS指令来完成操作。 (Edya Ladan-Mozes and Nir Shavit.An optimistic approach to

lock-free FIFO queues. Department of Computer Science, TelAviv University, Israel. Distributed Computing, 30 November 2007) 

 

可以去找来看一下。

 

 

3.  上面的提到的ABA 问题好像是无锁编程里面很主要的一个问题啊。

根据 cds 库的资料,有下面三类解决办法,可以去找论文来看一下。

 

M.Michael’s Hazard Pointer 

——————–

[2002] Maged M.Michael “Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes”

[2003] Maged M.Michael “Hazard Pointers: Safe memory reclamation for lock-free objects”

[2004] Andrei Alexandrescy, Maged Michael “Lock-free Data Structures with Hazard Pointers”

——————–

Gidenstam’s memory reclamation schema based on Hazard Pointer and reference counting 

 

[2006] A.Gidenstam “Algorithms for synchronization and consistency in concurrent system services”, Chapter 5 “Lock-Free Memory Reclamation” Thesis for the degree of Doctor of Philosophy

[2005] Anders Gidenstam, Marina Papatriantafilou and Philippas Tsigas “Allocating memory in a lock-free manner”, Proceedings of the 13th Annual European Symposium on Algorithms (ESA 2005), Lecture Notes in Computer Science Vol. 3669, pages 229 – 242, Springer-Verlag, 2005

——————–

M.Herlihy and M.Moir’s Pass The Buck algorithm 

 

[2002] M. Herlihy, V. Luchangco, and M. Moir. The repeat offender problem: A mechanism for supporting dynamic-sized lockfree data structures. Technical Report TR-2002-112, Sun Microsystems Laboratories, 2002

[2002] M. Herlihy, V. Luchangco, P. Martin, and M. Moir. Dynamic-sized Lockfree Data Structures. Technical Report TR-2002-110, Sun Microsystems Laboratories, 2002

[2005] M. Herlihy, V. Luchangco, P. Martin, and M. Moir. Nonblocking Memory Management Support for Dynamic_Sized Data Structures. ACM Transactions on Computer Systems, Vol.23, No.2, May 2005

———————-

 4. libcds库提到的其他无锁结构stack 和Split-Ordered List 等相关的论文

Treiber’s stack algorithm.

R. K. Treiber. Systems programming: Coping with

parallelism. Technical Report RJ 5118, IBM Almaden

Research Center, April 1986

 

 

Danny Hendler 等人的Treiber stack的改进

A Scalable Lock-free Stack Algorithm

http://www.cs.tau.ac.il/~shanir/nir-pubs-web/Papers/Lock_Free.pdf

 

———————

Michael’s hash map.

 

Source:

 

[2002] Maged Michael “High performance dynamic lock-free hash tables and list-based sets”

———————–

Hash table implementation based on split-ordered list algorithm discovered by Ori Shalev and Nir Shavit, see

 

[2003] Ori Shalev, Nir Shavit “Split-Ordered Lists – Lock-free Resizable Hash Tables”

[2008] Nir Shavit “The Art of Multiprocessor Programming”

 

5.  C++无锁数据结构支持库 CDS: Concurrent Data Structures library

http://libcds.sourceforge.net/

实现了很多无锁的stack(栈),queue(队列),hashmap ,list 等容器

前面说到的两个queue都有实现

1)Michael & Scott lock-free queue

2)Optimistic queue

3)cds::container::MichaelHashMap cds::container::MichaelHashSet

 

Intel® Threading Building Blocks  库(http://threadingbuildingblocks.org/)里面也有很多并行的 queue map等容器,但没说是不是无锁设计的。

最初是从 http://hi.baidu.com/ah__fu/blog/item/3081cd341a6364205ab5f5a4.html 看到这个库的介绍的。

 

6, The Art of Multiprocessor Programming.pdf  

一书对 无锁 queue stack 和skiplist  ABA问题都有所介绍,可以去看一下,写的不错的书。

 

7. 好像大家都期待一种叫做“Transac1tiona8l Memory”的最终解决方案来来彻底解决内存同步、无锁编程之类问题,不过好像没有到可用的程度吧。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143831.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JDBC从入门到精通

    JDBC从入门到精通JDBC概念我们学习了数据库,数据库实现了数据的持久化,但我们最终要在程序里处理数据啊,那java代码中怎么去访问数据库读写数据呢?这就要用到sun公司设定的一套数据库标准了,这套标准就是JDBC(JavaDatabaseConnectivity)。但它只是规范,不做具体实现。于是数据库厂商又根据JDBC标准,实现自家的驱动Driver。如:mysql驱动com.mysql.cj.jdbc.Driver,Oracle的驱动oracle.jdbc.OracleDriver。有了这套解决方案,java

    2022年6月23日
  • js数组添加删除数据_如何删除数组中的元素

    js数组添加删除数据_如何删除数组中的元素文章目录添加删除数组元素的方法添加删除数组元素的方法<script>//添加删除数组元素的方法//1.push()在我们数组的末尾添加一个或者多个数组元素vararr=[1,2,3];//arr.push(4,’Argonaut’)console.log(arr);console.log(arr.push(4,’Argonaut’));//

    2022年9月27日
  • PHP设计模式-工厂模式[通俗易懂]

    PHP设计模式-工厂模式[通俗易懂]PHP设计模式-工厂模式一、工厂模式概念工厂模式,顾名思义,像工厂的流水线,固定的规格,固定的材料,做固定的事情。工厂模式分为三种:简单工厂、工厂方法、抽象工厂,三种工厂的区别是,抽象工厂由多条产品线,而工厂方法只有一条产品线,是抽象工厂的简化。而工厂方法和简单工厂相对,大家初看起来好像工厂方法增加了许多代码但是实现的功能和简单工厂一样。但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则,模式只负责抽象工厂接口,具体工厂交给客.

    2022年7月25日
  • 2019年总结-做时间的朋友

    2019年总结-做时间的朋友插曲:抽风了,使用在线网页的markdown写2019年的总结,都快写完了,然后手欠点击了总结里贴的一个链接地址,页面毫不留情的跳转了。当我返回到写总结的页面时,发现写好的内容不见了,这是一种什么心情,我太南了~心情顿时不那么好了。重新理一下心情和思绪,简单整几句总结吧。2020年第一天,吃过晚饭,在电脑桌前,打开网易云音乐,播放了收藏的轻音乐,开始写下这些文…

    2022年2月28日
  • Z平台-开源免费的JAVA快速开发平台

    Z平台-开源免费的JAVA快速开发平台Z平台是开源免费的JavaWeb快速开发平台。通过Z平台集成开发环境,以零编码、动态配置的方式能够快速开发出各类Web管理系统。Z平台框架组成所用到的各种功能组件与框架,都是开源免费的,不涉及到版权问题,商业与非商业项目都可以使用。

    2022年5月14日
  • 【笔记】嵩天.Python语言程序设计.完成两个简单实例(温度转换和绘图)

    【笔记】嵩天.Python语言程序设计.完成两个简单实例(温度转换和绘图)PyCharm下编写、运行两个实例:温度转换,蟒蛇绘制

    2022年7月6日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号