参考资料: https://github.com/cameron314/readerwriterqueue
简介
项目名称: readerwriterqueue 作者: cameron314
类型: C++ 无锁队列库
核心库文件: readerwriterqueue.h, atomicops.h 命名空间: moodycamel
这是一个高性能、专注于 SPSC 场景、设计精良的 C++11 无锁队列实现。它通过模板化、预先内存分配、无等待算法以及针对现代处理器的优化,旨在提供极致性能。同时提供了阻塞版本以满足不同同步需求。集成简单,文档清晰,适合需要低延迟、高吞吐量数据传输的并发编程场景。使用时需注意其线程角色固定以及阻塞 API 的生命周期约束。
核心特性与设计
- 单生产者单消费者 (SPSC): 专为两个固定角色的线程(一个生产,一个消费)设计的高性能场景。
- 无锁 (Lock-Free): 避免使用互斥锁,通过原子操作实现线程安全,减少上下文切换和竞争开销。
- 完全通用模板: 像
std::queue一样,可容纳任意类型,内部管理内存。 - 预先分配连续内存: 提升缓存效率。支持初始容量设置 (
ReaderWriterQueue<int> q(100))。 - 动态扩容:
enqueue方法在队列满时可自动扩容。 - 非分配入队:
try_enqueue保证在初始容量内不进行内存分配,适合实时性要求高的场景。 - 原地构造: 支持
try_emplace/emplace,避免不必要的拷贝或移动。 - 完全无等待 (Wait-Free): 每个入队/出队操作都有确定性的、有限的步骤完成(O(1)),无忙等循环。
- 高效内存屏障: 在 x86 等强内存模型架构上,编译为高效指令(或空操作)。
- 窥视功能:
peek()允许消费者查看队首元素而不出队。
提供的队列类型
ReaderWriterQueue<T>: 基础的 SPSC 无锁队列。BlockingReaderWriterQueue<T>: 阻塞版本,增加了wait_dequeue和wait_dequeue_timed方法,消费者在队列为空时可阻塞等待。BlockingReaderWriterCircularBuffer<T>: 固定容量的阻塞环形缓冲区,同时提供wait_enqueue和wait_dequeue,使得生产者和消费者在队列满/空时都可阻塞。
使用要点
- 编译器要求: C++11 及以上。GCC >= 4.7, MSVC >= 2010。
- 基本API:
- 非阻塞:
enqueue,try_enqueue,try_dequeue,peek - 阻塞:
wait_dequeue,wait_dequeue_timed(仅阻塞版本)
- 非阻塞:
- 内存与生命周期警告:
- 使用
wait_dequeue时必须确保队列最终会有新元素,或者队列对象本身不会被提前销毁,否则会导致未定义行为。
- 使用
- 平台要求: 依赖对齐整数/指针访问的原子性。适用于所有现代主流架构(x86, ARM, PowerPC)。未在弱内存模型(如 DEC Alpha)上测试。
集成方式
- 直接包含头文件: 最简单,将
.h文件放入项目。 - CMake FetchContent: 现代 CMake 项目推荐方式,可自动下载和管理依赖。
- 系统安装: 通过 CMake 安装到系统目录,然后像标准库一样
#include <readerwriterqueue/readerwriterqueue.h>。
项目结构
根据文档内容,该项目包含以下主要功能模块:
核心队列模块
1. ReaderWriterQueue(基础 SPSC 队列)
- 核心功能:单生产者、单消费者的无锁队列
- 特性:
- 完全无锁且等待无关
- 内存预分配,支持固定容量
- 提供
try_enqueue/try_dequeue非阻塞方法 - 提供
enqueue/dequeue可能动态扩容的方法 - 支持 C++11 移动语义
- 提供
peek()方法查看队首元素
2. BlockingReaderWriterQueue(阻塞队列)
- 核心功能:在基础队列上增加阻塞功能
- 特性:
- 继承基础队列的所有特性
- 新增
wait_dequeue()方法:完全阻塞等待,直到有元素可出队 - 新增
wait_dequeue_timed()方法:支持超时的阻塞等待 - 注意:队列销毁时不能有线程在等待
3. BlockingReaderWriterCircularBuffer(阻塞环形缓冲区)
- 核心功能:固定容量的阻塞环形缓冲区
- 特性:
- 固定容量,不会动态扩容
- 支持阻塞入队和出队
- 新增
wait_enqueue():阻塞等待直到有空槽位 - 新增
wait_enqueue_timed():带超时的阻塞入队 - 同样支持 peek() 和 try_pop() 操作
支持模块
4. 原子操作抽象层(atomicops.h)
- 功能:平台特定的原子操作和内存屏障抽象
- 支持平台:
- GCC/Clang 的
__atomic_thread_fence - MSVC 的
_ReadWriteBarrier - ICC 的内置函数
- GCC/Clang 的
- 目的:确保跨编译器的内存顺序一致性
5. 构建与集成模块
- CMake 支持:提供现代 CMake 集成方式
- 两种使用模式:
- 直接包含头文件(最简单)
- 通过 CMake 的 FetchContent 或系统安装
辅助模块
6. 测试套件(tests 目录)
- 包含各种使用场景的测试
- 确保队列在不同条件下的正确性
7. 性能基准测试(benchmarks 目录)
- 提供性能对比测试
- 帮助用户评估队列在不同场景下的性能表现
源码阅读
atomicops.h
atomicops.h 是一个跨平台的原子操作和同步原语实现库。