我可以制作一个线程安全的 std::atomic<vector<int>>吗?
Can I make a thread-safe std::atomic<vector<int>>?
我有一个需要执行n=1000
次的函数。这个函数进行蒙特卡罗风格的模拟,并返回一个int
作为结果。我想并行运行nthreads=4
。每当线程完成一个循环时,它应该将结果放入std::vector<int>
中。因此,在1000个循环之后,我有一个1000个int
s的向量,可以通过统计来检查。
由于std::vector
不是线程安全的,我考虑了std::mutex
(这肯定会工作)。
但我想知道我是否可以声明一个向量是原子,从而绕过互斥体?有可能有std::atomic<std::vector<int>>
吗?我可以在上面使用push_back
等吗?
c++ 11§29.5/1说
有一个泛型类模板原子。模板实参T的类型必须是可复制的(3.9)。
trivial copyable是什么意思?
§3.9告诉
标量类型、平凡可复制类类型(第9节)、此类类型的数组以及这些类型的cv限定版本(3.9.3节)统称为平凡可复制类型。
对于类类型(std::vector
属于该类类型):
一个普通的可复制类是这样一个类:
- 没有非平凡的复制构造函数
- 没有非平凡移动构造函数
- 没有非平凡的拷贝赋值操作符
- 没有非平凡移动赋值操作符
- 有一个简单的析构函数
根据这个列表,std::vector
不是一般的可复制的,所以你不能使用std::atomic<std::vector<int>>
。
由于事先知道vector的大小,并且不需要使用需要将vector重新分配到不同位置的方法(如push_back)
)。您可以使用std::vector<int>::resize
或size构造函数来预分配和预构造所需的int
s。因此,你的并发线程不需要操作vector本身,而需要操作vector的元素。
如果不同线程对同一个元素没有访问,则不存在竞争条件。
同样适用于int k[1000]
,它是微不足道的可复制的。但是你不需要这样做,因为线程不会改变数组/向量/列表本身,而是元素。
你不需要。从多个线程访问std::vector
是完全可以的,如果
- 你读取对象
- 向写入不同的对象
所以只要确保,你创建一个大小为n=1000
的矢量,并根据你的线程号(1到4),你分配元素0-249,250-499等到你的线程。
所以你的每个线程计算n/nthreads
元素
Atomic可以用平凡的可复制类型实例化。Vector不是这样的类型
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中