boost::lockfree使用介绍
使用 介绍 Boost LockFree
2023-06-13 09:12:16 时间
大家好,又见面了,我是你们的朋友全栈君。
boost::lockfree是boost1.53引入的无锁数据结构,包括boost::lockfree::stack、boost::lockfree::queue和boost::lockfree::spsc_queue三种,前两种用于多生产者/多消费者场景,第三个用于单生产者/单消费者场景,下面对它们的使用进行详细介绍,以boost::lockfree::stack为例,其他类似。
构造
boost::lockfree::stack源代码如下(boost 1.65):
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES template <typename T, class A0, class A1, class A2> #else template <typename T, typename ...Options> #endif class stack { private: #ifndef BOOST_DOXYGEN_INVOKED BOOST_STATIC_ASSERT(boost::is_copy_constructible<T>::value); #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES typedef typename detail::stack_signature::bind<A0, A1, A2>::type bound_args; #else typedef typename detail::stack_signature::bind<Options...>::type bound_args; #endif static const bool has_capacity = detail::extract_capacity<bound_args>::has_capacity; static const size_t capacity = detail::extract_capacity<bound_args>::capacity; static const bool fixed_sized = detail::extract_fixed_sized<bound_args>::value; static const bool node_based = !(has_capacity || fixed_sized); static const bool compile_time_sized = has_capacity; /* 省略 */ public: typedef T value_type; typedef typename implementation_defined::allocator allocator; typedef typename implementation_defined::size_type size_type; //! Construct stack // @{ stack(void): pool(node_allocator(), capacity) { BOOST_ASSERT(has_capacity); initialize(); } template <typename U> explicit stack(typename node_allocator::template rebind<U>::other const & alloc): pool(alloc, capacity) { BOOST_STATIC_ASSERT(has_capacity); initialize(); } explicit stack(allocator const & alloc): pool(alloc, capacity) { BOOST_ASSERT(has_capacity); initialize(); } // @} //! Construct stack, allocate n nodes for the freelist. // @{ explicit stack(size_type n): pool(node_allocator(), n) { BOOST_ASSERT(!has_capacity); initialize(); } template <typename U> stack(size_type n, typename node_allocator::template rebind<U>::other const & alloc): pool(alloc, n) { BOOST_STATIC_ASSERT(!has_capacity); initialize(); }
boost::lockfree::stack的第一个模板参数是元素类型,后面3个参数是用来配置stack的,没有顺序要求:
- boost::lockfree::fixed_sized:是否固定大小,默认为
boost::lockfree::fixed_sized<false>
,如果为true,则内部使用数组保存元素,大小不能动态增长; - boost::lockfree::capacity:编译时设置内部数组大小,设置了capacity意味着一定是
boost::lockfree::fixed_sized<true>
,和运行时指定大小是互斥的,见下面的例子; - boost::lockfree::allocator:设置分配器,默认
boost::lockfree::allocator<std::allocator<void>>
。
例如:
//表示动态大小,初始大小为4,用完了再动态增长;此时必须在构造函数指定初始大小,否则断言失败;
boost::lockfree::stack<int> s(4);
//表示大小固定,运行时指定初始大小为4,用完后再push就会失败;此时必须在构造函数指定初始大小,否则断言失败;
boost::lockfree::stack<int, boost::lockfree::fixed_sized<true>> s1(4);
//表示大小固定,编译时指定初始大小为4,用完后再push就会失败;此时不能在构造函数指定初始大小,否则断言失败;
boost::lockfree::stack<int, boost::lockfree::capacity<4>> s2;
//和上面一样,设置了capacity,fixed_size就总是true
boost::lockfree::stack<int, boost::lockfree::fixed_size<false>, boost::lockfree::capacity<4>> s3;
成员方法
- push:压入一个元素到容器,除了unsynchronized_,都是线程安全的。所有都是非阻塞的。
bool push(T const & v)
bool bounded_push(T const & v)
template <typename ConstIterator>
ConstIterator push(ConstIterator begin, ConstIterator end)
template <typename ConstIterator>
ConstIterator bounded_push(ConstIterator begin, ConstIterator end)
bool unsynchronized_push(T const & v)
ConstIterator unsynchronized_push(ConstIterator begin, ConstIterator end)
bounded_表示不动态增长,当初始大小用完后再push就会失败; unsynchronized_表示非线程安全;
- pop:从容器中弹出一个元素,除了unsynchronized_,都是线程安全的。所有都是非阻塞的。
bool pop(T & ret)
template <typename U>
bool pop(U & ret)
bool unsynchronized_pop(T & ret)
template <typename U>
bool unsynchronized_pop(U & ret)
unsynchronized_表示非线程安全;
- consume_:从容器弹出1个或全部元素,并应用某个函数对象。线程安全或阻塞与否取决于函数对象。
template <typename Functor>
bool consume_one(Functor & f)
template <typename Functor>
bool consume_one(Functor const & f)
template <typename Functor>
size_t consume_all(Functor & f)
template <typename Functor>
size_t consume_all(Functor const & f)
template <typename Functor>
size_t consume_all_atomic(Functor & f)
template <typename Functor>
size_t consume_all_atomic(Functor const & f)
template <typename Functor>
size_t consume_all_atomic_reversed(Functor & f)
template <typename Functor>
size_t consume_all_atomic_reversed(Functor const & f)
_one表示只消费1个元素; _all表示消费所有元素; _atomic表示消费过程是原子的,其间其他操作对其是不可见的。 _reversed表示倒序消费。
- 其他
//预分配空闲节点数,和编译时设置capacity互斥;线程安全,可能阻塞
void reserve(size_type n)
//非线程安全
void reserve_unsafe(size_type n)
//判断是否为空
bool empty(void) const
简单示例
#include <boost/lockfree/stack.hpp>
int main(int argc, char *argv[])
{
boost::lockfree::stack<int> s(64);
//producer
for (int i = 0; i < 1000; i++)
{
s.push(i);
}
//consumer
s.consume_all([](int i)
{
std::cout << i << std::endl;
});
return 0;
}
转载于:https://www.cnblogs.com/zhongpan/p/7526903.html
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/161706.html原文链接:https://javaforall.cn
相关文章
- ZooKeeper入门(二):ZooKeeper常用命令介绍及使用Curator客户端实现分布式配置中心
- UUID介绍与使用范围
- 马上都2023了,但是CNS级别单细胞文章仍然是使用monocle2
- Android JetPack~ LiveData (一) 介绍与使用
- axios 介绍及引入使用
- Oracle 视图 DBA_LIBRARIES 官方解释,作用,如何使用详细说明
- 不怕蓝屏不怕挂!Windows系统备份与还原工具介绍和使用教程
- 使用Oracle实现列数据复制(oracle列复制)
- business suite使用Oracle EBusiness Suite实现企业管理效率提升(oraclee)
- MySQL中实现取字符的函数使用(mysql取字符函数)
- 如何使用Linux命令行查看进程状态:Top命令介绍(linux查看top)
- 使用MongoDB的in操作符查询特定条件下的数据(mongodbin)
- 如何使用 Linux 查看当前连接数?(linux查看连接数)
- MSSQL中使用注释符号的简单介绍(mssql的注释符)
- 如何使用Oracle中的写列语句(oracle写列语句)
- redis锁的使用方法介绍 (redis锁怎么用)
- 在同一窗体中使用PHP来处理多个提交任务
- jQuery层次选择器选择元素使用介绍
- Oracle中SQL语句连接字符串的符号使用介绍
- 关于使用coreseek并为其做分页的介绍
- java反射技术与类使用示例
- IIS6.0应用程序池回收和工作进程使用介绍