一无锁队列概述
1.需求
生产环境中广泛使用生产者和消费者模型,要求生产者在生产的同时,消费者可以进行消费,通常使用互斥锁保证数据同步。但线程互斥锁的开销仍然比较大,因此在要求高性能、低延时场景中,推荐使用无锁队列
2.前提
CAS即Compare and Swap,是所有CPU指令都支持CAS的原子操作(X86中CMPXCHG汇编指令),用于实现实现各种无锁(lock free)数据结构。
CAS操作的C语言实现如下:
bool compare_and_swap ( int *memory_location, int expected_value, int new_value)
{
if (*memory_location == expected_value)
{
*memory_location = new_value;
return true;
}
return false;
}
CAS用于检查一个内存位置是否包含预期值,如果包含,则把新值复赋值到内存位置。成功返回true,失败返回false。
a。GCC对CAS的支持
b。windows对CAS的支持
LONG InterlockedComapreExchange(...)
c。C++11 对CAS的支持
atomic函数支持CAS并可以跨平台。
template< class T >
bool atomic_compare_exchange_weak( std::atomic* obj,T* expected, T desired );
template< class T >
bool atomic_compare_exchange_weak( volatile std::atomic* obj,T* expected, T desired );
其它原子操作如下:
Fetch-And-Add:一般用来对变量做+1的原子操作
Test-and-set: 写值到某个内存位置并传回其旧值
d。boost方案的介绍
不是真正意义的无锁
boost提供了三种无锁方案,分别适用不同使用场景。
boost::lockfree::queue是支持多个生产者和多个消费者线程的无锁队列。
boost::lockfree::stack是支持多个生产者和多个消费者线程的无锁栈。
boost::lockfree::spsc_queue是仅支持单个生产者和单个消费者线程的无锁队列,比boost::lockfree::queue性能更好。
Boost无锁数据结构的API通过轻量级原子锁实现lock-free,不是真正意义的无锁。
Boost提供的queue可以设置初始容量,添加新元素时如果容量不够,则总容量自动增长;但对于无锁数据结构,添加新元素时如果容量不够,总容量不会自动增长。
3.业界例子
(1)ConcurrentQueue
ConcurrentQueue是基于C实现的工业级无锁队列方案。
GitHub:https://github.com/cameron314/concurrentqueue
ReaderWriterQueue是基于C实现的单生产者单消费者场景的无锁队列方案。
GitHub:https://github.com/cameron314/readerwriterqueue
(2)Disruptor
Disruptor是英国外汇交易公司LMAX基于JAVA开发的一个高性能队列。
GitHub:https://github.com/LMAX-Exchange/disruptor
二。无锁队列实现描述
1.环形缓冲区
2.单生产者单消费者
3.多生产者多消费者
4.RingBuffer实现
5.LockFreeQueue实现
备注:单生产者单消费者模式可以使用真正无锁设计,多生产者多消费者模式必须加锁,通常加原子锁,也可以加互斥锁。
原文连接:https://blog.51cto.com/quantfabric/2588193
三。kfifo内核队列
1.kfifo介绍
2.kfifo内核实现
3.kfifo实现要点
原文连接:https://blog.51cto.com/quantfabric/2588193