boost::lockfree::queue
// In header: <boost/lockfree/queue.hpp> template<typename T, typename... Options> class queue { public: // types typedef T value_type; typedef implementation_defined::allocator allocator; typedef implementation_defined::size_type size_type; // public member functions bool is_lock_free(void) const; queue(void); template<typename U, typename Enabler = std::enable_if< has_capacity > > explicit queue(typename boost::allocator_rebind< node_allocator, U >::type const &); template<typename Enabler = std::enable_if< has_capacity > > explicit queue(allocator const &); template<typename Enabler = std::enable_if< !has_capacity > > explicit queue(size_type); template<typename U, typename Enabler = std::enable_if< !has_capacity > > queue(size_type, typename boost::allocator_rebind< node_allocator, U >::type const &); template<typename Enabler = std::enable_if< !has_capacity > > queue(size_type, allocator const &); queue(const queue &) = delete; queue & operator=(const queue &) = delete; queue(queue &&) = delete; queue & operator=(queue &&) = delete; void reserve(size_type); void reserve_unsafe(size_type); ~queue(void); bool empty(void) const; bool push(const T &); bool push(T &&); bool bounded_push(const T &); bool bounded_push(T &&); bool unsynchronized_push(T &&); bool pop(T &); template<typename U> bool pop(U &); std::optional< T > pop(uses_optional_t); template<typename U> std::optional< U > pop(uses_optional_t); bool unsynchronized_pop(T &); template<typename U> bool unsynchronized_pop(U &); template<typename Functor> bool consume_one(Functor &&); template<typename Functor> size_t consume_all(Functor &&); };
queue 类提供了一个多写/多读队列,push 和 pop 操作是无锁的,构造/析构必须同步。它使用一个空闲列表进行内存管理,释放的节点被推送到空闲列表,并且在队列销毁之前不会返回给操作系统。
策略
boost::lockfree::fixed_sized,默认为 boost::lockfree::fixed_sized<false>
可以用于完全禁用 push 操作期间的动态内存分配,以确保无锁行为。
如果数据结构配置为固定大小,则内部节点存储在数组中,并通过数组索引进行寻址。 这将队列的可能大小限制为索引类型可以寻址的元素数量(通常为 2**16-2),但是在缺少双宽度比较和交换指令的平台上,这是实现无锁的最佳方法。
boost::lockfree::capacity,可选
如果此模板参数传递给选项,则队列的大小将在编译时设置。
此选项意味着 fixed_sized<true>
boost::lockfree::allocator,默认为 boost::lockfree::allocator<std::allocator<void>>
指定用于内部空闲列表的分配器
要求
T 必须具有复制构造函数
T 必须具有平凡赋值运算符
T 必须具有平凡析构函数
queue
公有成员函数bool is_lock_free(void) const;
![]() |
警告 |
---|---|
它仅检查队列头尾节点和空闲列表是否可以以无锁方式修改。 在大多数平台上,如果这是真的,则整个实现是无锁的。 使用 c++0x 风格的原子操作,不可能提供完全准确的实现,因为需要测试每个内部节点,如果将来会从操作系统分配更多节点,这是不可能的。 |
返回值 |
true,如果实现是无锁的。 |
queue(void);
构造一个固定大小的队列
要求 |
必须指定 capacity<> 参数 |
template<typename U, typename Enabler = std::enable_if< has_capacity > > explicit queue(typename boost::allocator_rebind< node_allocator, U >::type const & alloc);
构造一个具有自定义分配器的固定大小队列
要求 |
必须指定 capacity<> 参数 |
template<typename Enabler = std::enable_if< has_capacity > > explicit queue(allocator const & alloc);
构造一个具有自定义分配器的固定大小队列
要求 |
必须指定 capacity<> 参数 |
template<typename Enabler = std::enable_if< !has_capacity > > explicit queue(size_type n);
构造一个可变大小的队列
为 freelist 初始分配 n 个节点
要求 |
必须不指定 capacity<> 参数 |
template<typename U, typename Enabler = std::enable_if< !has_capacity > > queue(size_type n, typename boost::allocator_rebind< node_allocator, U >::type const & alloc);
构造一个具有自定义分配器的可变大小队列
为 freelist 初始分配 n 个节点
要求 |
必须不指定 capacity<> 参数 |
template<typename Enabler = std::enable_if< !has_capacity > > queue(size_type n, allocator const & alloc);
构造一个具有自定义分配器的可变大小队列
为 freelist 初始分配 n 个节点
要求 |
必须不指定 capacity<> 参数 |
queue(const queue &) = delete;
queue & operator=(const queue &) = delete;
queue(queue &&) = delete;
queue & operator=(queue &&) = delete;
void reserve(size_type n);
为 freelist 分配 n 个节点
![]() |
注意 |
---|---|
线程安全,如果内存分配器阻塞,则可能阻塞 |
要求 |
仅当未给定 capacity<> 参数时有效 |
void reserve_unsafe(size_type n);
为 freelist 分配 n 个节点
![]() |
注意 |
---|---|
非线程安全,如果内存分配器阻塞,则可能阻塞 |
要求 |
仅当未给定 capacity<> 参数时有效 |
~queue(void);
销毁队列,释放来自 freelist 的所有节点。
bool empty(void) const;
检查队列是否为空
![]() |
注意 |
---|---|
只有在没有其他线程修改队列的情况下,结果才是准确的。 因此,在程序逻辑中使用此值很少实用。 |
返回值 |
true,如果队列为空,否则为 false |
bool push(const T & t);
将对象 t 推送到队列。
![]() |
注意 |
---|---|
线程安全。 如果内部内存池耗尽且内存池不是固定大小,则将从操作系统分配新节点。 这可能不是无锁的。 |
后置条件 |
如果可以分配内部节点,则对象将被推送到队列 |
返回值 |
true,如果 push 操作成功。 |
bool push(T && t);
将对象 t 推送到队列。
![]() |
注意 |
---|---|
线程安全。 如果内部内存池耗尽且内存池不是固定大小,则将从操作系统分配新节点。 这可能不是无锁的。 |
后置条件 |
如果可以分配内部节点,则对象将被推送到队列 |
返回值 |
true,如果 push 操作成功。 |
bool bounded_push(const T & t);
将对象 t 推送到队列。
![]() |
注意 |
---|---|
线程安全且非阻塞。 如果内部内存池耗尽,操作将失败 |
后置条件 |
如果可以分配内部节点,则对象将被推送到队列 |
返回值 |
true,如果 push 操作成功。 |
抛出 |
如果内存分配器抛出异常 |
bool bounded_push(T && t);
将对象 t 推送到队列。
![]() |
注意 |
---|---|
线程安全且非阻塞。 如果内部内存池耗尽,操作将失败 |
后置条件 |
如果可以分配内部节点,则对象将被推送到队列 |
返回值 |
true,如果 push 操作成功。 |
抛出 |
如果内存分配器抛出异常 |
bool unsynchronized_push(T && t);
将对象 t 推送到队列。
![]() |
注意 |
---|---|
非线程安全。 如果内部内存池耗尽且内存池不是固定大小,则将从操作系统分配新节点。 这可能不是无锁的。 |
后置条件 |
如果可以分配内部节点,则对象将被推送到队列 |
返回值 |
true,如果 push 操作成功。 |
抛出 |
如果内存分配器抛出异常 |
bool pop(T & ret);
从队列中弹出对象。
![]() |
注意 |
---|---|
线程安全且非阻塞。 即使操作失败,也可能会修改返回参数。 |
后置条件 |
如果 pop 操作成功,对象将被复制到 ret。 |
返回值 |
true,如果 pop 操作成功,如果队列为空则为 false。 |
template<typename U> bool pop(U & ret);
从队列中弹出对象。
![]() |
注意 |
---|---|
线程安全且非阻塞。 即使操作失败,也可能会修改返回参数。 |
要求 |
类型 U 必须可以通过 T 构造和复制,或者 T 必须可转换为 U |
后置条件 |
如果 pop 操作成功,对象将被复制到 ret。 |
返回值 |
true,如果 pop 操作成功,如果队列为空则为 false。 |
std::optional< T > pop(uses_optional_t);
从队列中弹出对象,返回 std::optional<>
![]() |
注意 |
---|---|
线程安全且非阻塞 |
返回值 |
|
template<typename U> std::optional< U > pop(uses_optional_t);
从队列中弹出对象,返回 std::optional<>
![]() |
注意 |
---|---|
线程安全且非阻塞 |
要求 |
类型 T 必须可转换为 U |
返回值 |
|
bool unsynchronized_pop(T & ret);
从队列中弹出对象。
![]() |
注意 |
---|---|
非线程安全,但非阻塞。 即使操作失败,也可能会修改返回参数。 |
后置条件 |
如果 pop 操作成功,对象将被复制到 ret。 |
返回值 |
true,如果 pop 操作成功,如果队列为空则为 false。 |
template<typename U> bool unsynchronized_pop(U & ret);
从队列中弹出对象。
![]() |
注意 |
---|---|
非线程安全,但非阻塞。 即使操作失败,也可能会修改返回参数。 |
要求 |
类型 U 必须可以通过 T 构造和复制,或者 T 必须可转换为 U |
后置条件 |
如果 pop 操作成功,对象将被复制到 ret。 |
返回值 |
true,如果 pop 操作成功,如果队列为空则为 false。 |
template<typename Functor> bool consume_one(Functor && f);
通过 functor 消费一个元素
从队列中弹出一个元素,并将 functor 应用于此对象
![]() |
注意 |
---|---|
线程安全且非阻塞,如果 functor 是线程安全且非阻塞的 |
返回值 |
true,如果消费了一个元素 |
template<typename Functor> size_t consume_all(Functor && f);
通过 functor 消费所有元素
顺序地从队列中弹出所有元素,并将 functor 应用于每个对象
![]() |
注意 |
---|---|
线程安全且非阻塞,如果 functor 是线程安全且非阻塞的 |
返回值 |
已消费的元素数量 |