我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++BoostLockfree超详细讲解使用方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++BoostLockfree超详细讲解使用方法

Boost.Lockfree

一、说明

Boost.Lockfree 提供线程安全和无锁容器。可以从多个线程访问此库中的容器,而无需同步访问。

在 1.56.0 版本中,Boost.Lockfree 只提供了两个容器:boost::lockfree::queue 类型的队列和 boost::lockfree::stack 类型的栈。对于队列,可以使用第二个实现:boost::lockfree::spsc_queue。此类针对只有一个线程写入队列和只有一个线程从队列读取的用例进行了优化。类名中的缩写 spsc 代表单一生产者/单一消费者。

二、示例和代码

示例 46.1。使用 boost::lockfree::spsc_queue

#include <boost/lockfree/spsc_queue.hpp>
#include <thread>
#include <iostream>
boost::lockfree::spsc_queue<int> q{100};
int sum = 0;
void produce()
{
  for (int i = 1; i <= 100; ++i)
    q.push(i);
}
void consume()
{
  int i;
  while (q.pop(i))
    sum += i;
}
int main()
{
  std::thread t1{produce};
  std::thread t2{consume};
  t1.join();
  t2.join();
  consume();
  std::cout << sum << '\n';
}

Example46.1

示例 46.1 使用容器 boost::lockfree::spsc_queue。第一个执行函数 produce() 的线程将数字 1 到 100 添加到容器中。第二个线程执行 consume(),从容器中读取数字并将它们相加。因为容器 boost::lockfree::spsc_queue 明确支持来自两个线程的并发访问,所以不需要同步线程。

请注意,函数 consume() 会在线程终止后被第二次调用。这需要计算所有 100 个数字的总数,即 5050。因为 consume() 在循环中访问队列,它读取数字的速度可能比 produce() 插入数字的速度快。如果队列为空,pop() 返回 false。因此,执行 consume() 的线程可能会终止,因为另一个线程中的 produce() 无法足够快地填充队列。如果执行 produce() 的线程终止,那么很明显所有数字都已添加到队列中。第二次调用 consume() 确保将可能尚未读取的数字添加到 sum 中。

队列的大小被传递给构造函数。因为 boost::lockfree::spsc_queue 是用循环缓冲区实现的,所以示例 46.1 中的队列容量为 100 个元素。如果由于队列已满而无法添加值,则 push() 返回 false。该示例不检查 push() 的返回值,因为恰好有 100 个数字被添加到队列中。因此,100 个元素就足够了。

示例 46.2。 boost::lockfree::spsc_queue 和 boost::lockfree::capacity

#include <boost/lockfree/spsc_queue.hpp>
#include <boost/lockfree/policies.hpp>
#include <thread>
#include <iostream>
using namespace boost::lockfree;
spsc_queue<int, capacity<100>> q;
int sum = 0;
void produce()
{
  for (int i = 1; i <= 100; ++i)
    q.push(i);
}
void consume()
{
  while (q.consume_one([](int i){ sum += i; }))
    ;
}
int main()
{
  std::thread t1{produce};
  std::thread t2{consume};
  t1.join();
  t2.join();
  q.consume_all([](int i){ sum += i; });
  std::cout << sum << '\n';
}

Example46.2

示例 46.2 与前面的示例类似,但这次循环缓冲区的大小是在编译时设置的。这是通过模板 boost::lockfree::capacity 完成的,它需要容量作为模板参数。 q 是用默认构造函数实例化的——容量不能在运行时设置。

函数 consume() 已更改为使用 consume_one() 而不是 pop() 来读取数字。 lambda 函数作为参数传递给 consume_one()。 consume_one() 就像 pop() 一样读取一个数字,但该数字不是通过对调用者的引用返回的。它作为唯一参数传递给 lambda 函数。

当线程终止时,main() 调用成员函数 consume_all(),而不是 consume()。 consume_all() 的工作方式与 consume_one() 类似,但要确保队列在调用后为空。只要队列中有元素,consume_all() 就会调用 lambda 函数。

示例 46.2 再次将 5050 写入标准输出。

示例 46.3。具有可变容器大小的 boost::lockfree::queue

#include <boost/lockfree/queue.hpp>
#include <thread>
#include <atomic>
#include <iostream>
boost::lockfree::queue<int> q{100};
std::atomic<int> sum{0};
void produce()
{
  for (int i = 1; i <= 10000; ++i)
    q.push(i);
}
void consume()
{
  int i;
  while (q.pop(i))
    sum += i;
}
int main()
{
  std::thread t1{produce};
  std::thread t2{consume};
  std::thread t3{consume};
  t1.join();
  t2.join();
  t3.join();
  consume();
  std::cout << sum << '\n';
}

Example46.3

示例 46.3 在两个线程中执行 consume()。因为有多个线程从队列中读取,所以不得使用类 boost::lockfree::spsc_queue。此示例改为使用 boost::lockfree::queue。

多亏了 std::atomic,对变量 sum 的访问现在也是线程安全的。

队列的大小设置为 100——这是传递给构造函数的参数。但是,这只是初始大小。默认情况下,boost::lockfree::queue 不使用循环缓冲区实现。如果添加到队列中的项目多于设置的容量,则会自动增加。如果初始大小不够,boost::lockfree::queue 会动态分配额外的内存。

这意味着 boost::lockfree::queue 不一定是无锁的。 boost::lockfree::queue 默认使用的分配器是 boost::lockfree::allocator,它基于 std::allocator。因此,此分配器确定 boost::lockfree::queue 是否是无约束的无锁。

#include <boost/lockfree/queue.hpp>
#include <thread>
#include <atomic>
#include <iostream>
using namespace boost::lockfree;
queue<int, fixed_sized<true>> q{10000};
std::atomic<int> sum{0};
void produce()
{
  for (int i = 1; i <= 10000; ++i)
    q.push(i);
}
void consume()
{
  int i;
  while (q.pop(i))
    sum += i;
}
int main()
{
  std::thread t1{produce};
  std::thread t2{consume};
  std::thread t3{consume};
  t1.join();
  t2.join();
  t3.join();
  consume();
  std::cout << sum << '\n';
}

Example46.4

示例 46.3 在两个线程中执行 consume()。因为有多个线程从队列中读取,所以不得使用类 boost::lockfree::spsc_queue。此示例改为使用 boost::lockfree::queue。

多亏了 std::atomic,对变量 sum 的访问现在也是线程安全的。

队列的大小设置为 100——这是传递给构造函数的参数。但是,这只是初始大小。默认情况下,boost::lockfree::queue 不使用循环缓冲区实现。如果添加到队列中的项目多于设置的容量,则会自动增加。如果初始大小不够,boost::lockfree::queue 会动态分配额外的内存。

这意味着 boost::lockfree::queue 不一定是无锁的。 boost::lockfree::queue 默认使用的分配器是 boost::lockfree::allocator,它基于 std::allocator。因此,此分配器确定 boost::lockfree::queue 是否是无约束的无锁。

示例 46.4。具有恒定容器大小的 boost::lockfree::queue

到此这篇关于C++ Boost Lockfree超详细讲解使用方法的文章就介绍到这了,更多相关C++ Boost Lockfree内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++BoostLockfree超详细讲解使用方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++BoostLockfree超详细讲解使用方法

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
2022-11-21

C++ Boost Lockfree超详细讲解使用方法

Boost Lockfree 是一个基于 C++ 的库,用于实现无锁的数据结构和算法。无锁的数据结构和算法是为了解决并发编程中的竞争条件和锁竞争而设计的。由于无锁的数据结构和算法可以避免锁竞争,因此在高度并发的场景中,可以提供更好的性能和可
2023-08-16

C++BoostUtility超详细讲解

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
2022-12-08

C++BoostUuid超详细讲解

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
2022-12-08

C++ Boost Assign超详细讲解

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
2022-12-09

C++stack与queue使用方法详细讲解

stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作;队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素
2023-01-04

C++BoostAlgorithm算法超详细精讲

Boost.Algorithm提供了补充标准库算法的算法。与Boost.Range不同,Boost.Algorithm没有引入新概念。Boost.Algorithm定义的算法类似于标准库中的算法
2022-11-13

C++BoostGraph算法超详细精讲

这篇文章主要介绍了C++BoostGraph算法,我门尝试使用Boost.Graph库来运行Goldberg的最大流算法。Boost.Graph将其称为push_relabel_max_flow
2022-11-13

C++BoostPropertyTree示例超详细讲解

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
2022-11-13

C语言 详细讲解#pragma的使用方法

#pragma是C语言中的预处理指令,用于告诉编译器在编译过程中采取特定的行为。以下是#pragma的使用方法的详细讲解:1. #pragma once:这个指令放在头文件的开头,作用是确保头文件只被编译一次,避免重复包含。2. #prag
2023-08-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录