如何在 C++ 中声明原子向量

2023-11-24

我打算声明一个原子变量向量,用作多线程程序中的计数器。这是我尝试过的:

#include <atomic>
#include <vector>

int main(void)
{
  std::vector<std::atomic<int>> v_a;
  std::atomic<int> a_i(1);
  v_a.push_back(a_i);
  return 0;
}

这是 gcc 4.6.3 令人烦恼的冗长错误消息:

In file included from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34:0,
             from /usr/include/c++/4.6/bits/allocator.h:48,
             from /usr/include/c++/4.6/vector:62,
             from test_atomic_vec.h:2,
             from test_atomic_vec.cc:1:
/usr/include/c++/4.6/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, const _Tp&) [with _Tp = std::atomic<int>, __gnu_cxx::new_allocator<_Tp>::pointer = std::atomic<int>*]’:
/usr/include/c++/4.6/bits/stl_vector.h:830:6:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/ext/new_allocator.h:108:9: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:538:7: error: declared here
In file included from /usr/include/c++/4.6/vector:70:0,
             from test_atomic_vec.h:2,
             from test_atomic_vec.cc:1:
/usr/include/c++/4.6/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::atomic<int>&}, _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::atomic<int>*, std::vector<std::atomic<int> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::atomic<int>*]’:
/usr/include/c++/4.6/bits/stl_vector.h:834:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/bits/vector.tcc:319:4: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:538:7: error: declared here
/usr/include/c++/4.6/bits/stl_vector.h:834:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/bits/vector.tcc:319:4: error: use of deleted function ‘std::atomic<int>& std::atomic<int>::operator=(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:539:15: error: declared here
In file included from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34:0,
             from /usr/include/c++/4.6/bits/allocator.h:48,
             from /usr/include/c++/4.6/vector:62,
             from test_atomic_vec.h:2,
             from test_atomic_vec.cc:1:
/usr/include/c++/4.6/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, _Args&& ...) [with _Args = {std::atomic<int>}, _Tp = std::atomic<int>, __gnu_cxx::new_allocator<_Tp>::pointer = std::atomic<int>*]’:
/usr/include/c++/4.6/bits/vector.tcc:306:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::atomic<int>&}, _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::atomic<int>*, std::vector<std::atomic<int> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_vector.h:834:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/ext/new_allocator.h:114:4: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:538:7: error: declared here
In file included from /usr/include/c++/4.6/vector:61:0,
             from test_atomic_vec.h:2,
             from test_atomic_vec.cc:1:
/usr/include/c++/4.6/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = std::atomic<int>*, _BI2 = std::atomic<int>*]’:
/usr/include/c++/4.6/bits/stl_algobase.h:581:18:   instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = std::atomic<int>*, _BI2 = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_algobase.h:590:34:   instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = std::atomic<int>*, _BI2 = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_algobase.h:661:15:   instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = std::atomic<int>*, _BI2 = std::atomic<int>*]’
/usr/include/c++/4.6/bits/vector.tcc:313:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::atomic<int>&}, _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::atomic<int>*, std::vector<std::atomic<int> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_vector.h:834:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/bits/stl_algobase.h:546:6: error: use of deleted function ‘std::atomic<int>& std::atomic<int>::operator=(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:539:15: error: declared here
In file included from /usr/include/c++/4.6/vector:63:0,
             from test_atomic_vec.h:2,
             from test_atomic_vec.cc:1:
/usr/include/c++/4.6/bits/stl_construct.h: In function ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::atomic<int>, _Args = {std::atomic<int>}]’:
/usr/include/c++/4.6/bits/stl_uninitialized.h:77:3:   instantiated from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::atomic<int>*>, _ForwardIterator = std::atomic<int>*, bool _TrivialValueTypes = false]’
/usr/include/c++/4.6/bits/stl_uninitialized.h:119:41:   instantiated from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::atomic<int>*>, _ForwardIterator = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_uninitialized.h:259:63:   instantiated from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<std::atomic<int>*>, _ForwardIterator = std::atomic<int>*, _Tp = std::atomic<int>]’
/usr/include/c++/4.6/bits/stl_uninitialized.h:269:24:   instantiated from ‘_ForwardIterator std::__uninitialized_move_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = std::atomic<int>*, _ForwardIterator = std::atomic<int>*, _Allocator = std::allocator<std::atomic<int> >]’
/usr/include/c++/4.6/bits/vector.tcc:343:8:   instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::atomic<int>&}, _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::atomic<int>*, std::vector<std::atomic<int> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::atomic<int>*]’
/usr/include/c++/4.6/bits/stl_vector.h:834:4:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20:   instantiated from here
/usr/include/c++/4.6/bits/stl_construct.h:76:7: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:538:7: error: declared here

我该如何解决这个问题?

当我注释掉该行时,错误消失了push_back() .

edit:我编辑了这篇文章...对于那些看到第一篇文章的人来说,这个错误是令人尴尬的,因为我使用了gcc代替g++ :\


如本文所述密切相关的问题评论中提到的,std::atomic<T>不可复制构造,也不可复制分配。

不具有这些属性的对象类型不能用作std::vector.

但是,应该可以创建一个包装器std::atomic<T>可复制构造和可复制分配的元素。它将不得不使用load() and store()的成员函数std::atomic<T>提供构造和分配(这是上述问题的公认答案所描述的想法):

#include <atomic>
#include <vector>

template <typename T>
struct atomwrapper
{
  std::atomic<T> _a;

  atomwrapper()
    :_a()
  {}

  atomwrapper(const std::atomic<T> &a)
    :_a(a.load())
  {}

  atomwrapper(const atomwrapper &other)
    :_a(other._a.load())
  {}

  atomwrapper &operator=(const atomwrapper &other)
  {
    _a.store(other._a.load());
  }
};

int main(void)
{
  std::vector<atomwrapper<int>> v_a;
  std::atomic<int> a_i(1);
  v_a.push_back(a_i);
  return 0;
}

编辑:正如 Bo Persson 正确指出的那样,包装器执行的复制操作不是原子的。它使您能够复制原子对象,但副本本身不是原子的。这意味着对原子的任何并发访问都不得使用复制操作。这意味着对向量本身的操作(例如添加或删除元素)不得同时执行。

示例:如果一个线程修改存储在一个原子中的值,而另一个线程向向量添加新元素,则可能会发生向量重新分配,并且第一个线程修改的对象可能会从向量中的一个位置复制到另一个位置。在这种情况下,第一个线程执行的元素访问与第二个线程触发的复制操作之间会出现数据竞争。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C++ 中声明原子向量 的相关文章

随机推荐

  • Ruby:自动将实例变量设置为方法参数?

    是否有计划实现类似于 CoffeeScript 功能 在方法参数列表中指定实例变量名称 的 ruby 行为 喜欢 class User def initialize name age name is set implicitly but a
  • 使用目录将 IPython 笔记本写入 HTML 或 PDF

    我正在尝试从我的 IPython 笔记本创建报告 我使用目录扩展为我的笔记本创建目录 我已经将笔记本转换为 html 但目录未显示 也未链接到文档的其余部分 有没有什么方法可以转换为指定的格式之一并仍然保留可链接 甚至不可链接 的目录 我使
  • 如何覆盖 Android 中虚拟键盘的 键行为

    I want to override the behaviour of the ENTER key of the virtual keyboard so that 当屏幕上有更多字段时 它会 跳到 下一个字段 当它是屏幕的最后一个字段时 执
  • 如何获取特定页面的所有 Facebook 签到?

    我有一个 Facebook 页面 它也是 FB 中的一个位置 因此用户可以签到该位置 例如使用 iPhone 现在我想从我的页面获取所有签入的用户 但即使有多个用户签入 我总是得到一个空数组 我使用 Graph API 中的以下 URI h
  • 确定 T-SQL 中的时区偏移

    我的数据库应用程序将部署在不同时区的多个站点 我需要一个 T SQL 函数来确定当年 1 月 1 日午夜的 UTC 时间戳 以进行 YTD 计算 所有数据都存储在 UTC 时间戳中 例如 芝加哥采用 UTC 6 夏令时 DST 如果该函数在
  • CURL 不编码 UTF-8

    我在用着Windows 10 and 卷曲7 52 1 当我尝试POST数据到 WEBSERVICE curl没有将字符编码为UTF 8 我需要显示pt BR字符 例如 etc 是的 我已经检查过this 没有成功 如果我将编码页面设置为c
  • Gradle 无法解析 Android Studio 中的库

    我想在 Android Studio 中包含一个库 但它显示如下错误 无法解析 com lemonlab expandable button menu 1 0 0 如何解决这个问题 apply plugin com android appl
  • 带有模板参数的 C++0x lambda? [复制]

    这个问题在这里已经有答案了 可能的重复 lambda 函数可以模板化吗 是否可以使用带有模板参数的 c 0x lambda 例如 template
  • 为 Linux 安装 Anaconda [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在尝试安装适用于 Linux 的 Anaconda Linux Mint 17 2 Rafaela 14 04 3 LTS Trusty Tahr 我看到一条警告 警告 机器似乎
  • 如果我的 url 包含路由参数,则哈希链接会以角度重新路由

    如果我有一个一级路由 那么哈希链接将按预期工作 无需重新路由 但是 我有一些国家 kh 的网址 如果我尝试使用诸如国家 kh projects 之类的哈希标签 页面会重新路由 这非常烦人 因此 如果我在页面国家 地区并单击链接 develo
  • 如果没有连续的内存空间,realloc 会做什么?

    realloc用于动态重新分配内存 假设我已经使用分配了 7 个字节malloc函数 现在我想将其扩展到 30 个字节 如果内存中没有30字节的连续 单行连续 空间 后台会发生什么 是否有任何错误或者内存是否会被分段分配 realloc幕后
  • MS Visual Studio 2010如何使用.asm生成的文件

    我想询问一些我想尝试使用 Visual Studio 2010 的事情 我通过在项目属性 gt C C gt 输出文件 FAs 中将选项设置为 汇编器输出 从 cpp 文件生成 asm 文件 我的问题是 下一步如何使用 asm 生成的文件从
  • 子类 UITableViewCell 中的 UIButton 需要调用父类的方法

    很抱歉 如果答案已经存在 但我找不到 我有以下设置 MainViewController 它有一个大的 UITableView 和 CustomTableViewCell 它是 UITableViewCell 的子类 CustomTable
  • 无法创建多可用区 Aurora RDS 实例

    当我恢复 MySQL 快照时 我可以选择将新实例设置为多可用区 但是 由于某种原因 当我恢复到 Aurora 时 多可用区部署 选择被禁用 我想这可能意味着它会自动启用 但是 当我转到正在运行的实例详细信息时 它特别列出了多可用区 否 我有
  • 检查核心数据中是否设置了属性?

    如何检查核心数据对象中是否设置了属性 我将所有核心数据对象加载到目录中 var formQuestions Questions 我的核心数据 NSManagementObject 是 NSManaged var noticeText Str
  • 如何在 this.props.children 中访问 React 对象的类名

    在一个 React 组件渲染方法中 在 this props children 中有一些子组件 如何获取每个子组件的组件 类 名称以区分它们 React Children map this props children function c
  • 将 .DLL 转换为 .SO

    你们中的任何人都可以帮我将 Windows dll 文件转换为 so 文件吗 您可以尝试将 dll 的源代码重新编译为共享对象 This在确保代码确实可移植后 可能会帮助您入门 Edit Here is 还有另一个链接它可以帮助指导您完成使
  • Xcode 正在 OS X 对象而不是 iOS 对象中加载

    我有一个 iOS 窗口应用程序 直到今天它都可以与 Xcode 正常运行 当我在对象库中打开项目时 它似乎加载了所有 OS X 开发对象 并且我再也看不到任何可可触摸项目 如 UITextViews 等 我没有手动更改任何设置 所以我不确定
  • 如何更改现有表以在 Oracle 中创建范围分区

    我现有的表包含 10 年的数据 我已转储 我想在表中的一个日期键列上对现有表进行范围分区 我看到的大多数例子都是CREATE TABLE PARTITION BY RANGE 添加新分区 但我的表是现有的表 我想我需要一些ALTER陈述 A
  • 如何在 C++ 中声明原子向量

    我打算声明一个原子变量向量 用作多线程程序中的计数器 这是我尝试过的 include