无锁队列

一个高性能无锁非阻塞链表队列

假装没事ソ 提交于 2020-04-07 06:03:02
这个是一个用c++ 11标准实现的无锁非阻塞链表队列,通过增加一个dummy节点,解偶合链表头指针和尾指针。使得当只有一个生产者和一个消费者时,进队和出队都无需加锁,进队操作的是尾指针,出队操作的是头指针,互不干涉。对于多个生产者且单个消费者时,只需要对尾指针加锁保护,而头指针不需要加锁。反之,对于单生产者且多消费者时,只需要对头指针加锁保护而尾指针不需要加锁。如果是多生产者和多消费者,那么头尾指针各自加锁保护。同时,队列内部会对节点进行缓存,避免重复的内存分配以提高性能。 在双cpu的机器上测试,性能比boost实现的单生产者和单消费者队列boost::lockfree::spsc_queue快6到7倍。 //对模板使用别名,方便使用(说明:NullMutex是一个空锁,是一个自旋锁spin_lock) //单生产者和单消费者 template<typename VALUE_TYPE> using spsc_queue = TDoubleLockLinkedNonBlockingQueue<VALUE_TYPE, NullMutex, NullMutex>; //多生产者和单消费者 template<typename VALUE_TYPE> using mpsc_queue = TDoubleLockLinkedNonBlockingQueue<VALUE_TYPE, spin

ZeroMQ无锁队列分析

牧云@^-^@ 提交于 2019-12-07 21:10:28
ZeroMQ无锁队列分析 1. 概述 ZeroMQ使用了一个无锁队列,用于线程间的高性能数据交换。这个无锁队列由两个对象组成: yqueue_t: 一个普通的队列,实现内存块链表,以及内存块的回收和重复利用。 ypipe_t: 基于yqueue_t实现的无锁管道队列,实现一读一写的无锁操作。 2. yqueue_t类 yqueue_t类实现了一个普通的队列(多线程不安全),但为了提高性能,使用了内存块链的方式,每个内存块可支持多个数据元素节点。 begin_chunk: 队列第一个内存块。 end_chunk: 队列最后一个内存块。 begin_pos: 队列中第一个元素在第一个内存块中的位置。 end_pos: 对垒中最后一个元素在最后一个内存块的位置。 同时为了减少内存的分配、释放操作,yqueue_t中包含了一个spare_chunk,存放一个空闲的内存块。该spare_chunk的首节点指针使用atomic变量存放,实现spare_chunk中存取的线程安全。 2.1 push操作 push操作实现向队列中增加一个空元素,此后可使用back方法获取新增元素的引用,然后将数据填入。简要操作过程: // end pos后移, 如果达到当前chunk末尾,就新增一个chunk. // 获取新chunk,可以从spare_chunk获取,也可能是重新内存分配。 if ( ++end