[英]Can I make a thread-safe std::atomic<vector<int>>?
我有一个需要执行n=1000
次的函数。 此函数执行蒙特卡罗风格模拟并返回一个int
作为结果。 我想并行运行nthreads=4
。 每当一个线程完成一个循环时,它应该将结果放入std::vector<int>
。 因此,在 1000 个周期后,我有一个 1000 个int
向量,可以通过统计检查。
由于std::vector
不是线程安全的,我想到了std::mutex
(这肯定会起作用)。
但是我想知道是否可以将向量声明为原子向量,从而绕过互斥锁? 是否有可能有一个std::atomic<std::vector<int>>
? 我可以在上面使用push_back
等吗?
C++11 §29.5/1 说
有一个泛型类模板原子。 模板参数 T 的类型应该是可简单复制的(3.9)。
可简单复制是什么意思?
§3.9 告诉
标量类型、可简单复制的类类型(第 9 条)、此类类型的数组以及这些类型的 cv 限定版本 (3.9.3) 统称为可简单复制的类型。
对于类类型(其中std::vector
是):
一个普通的可复制类是这样一个类:
- 没有非平凡的复制构造函数
- 没有非平凡的移动构造函数
- 没有非平凡的复制赋值运算符
- 没有重要的移动赋值运算符
- 有一个简单的析构函数
根据此列表, std::vector
不是可简单复制的,因此您不能使用std::atomic<std::vector<int>>
。
由于您事先知道大小,并且您不需要使用需要在不同位置重新分配向量的方法(如push_back)
。 您可以使用std::vector<int>::resize
或 size 构造函数来预分配和预构造所需的int
。 因此,您的并发线程不需要对向量本身进行操作,而是对元素进行操作。
如果不同线程无法访问同一元素,则不存在竞争条件。
对于可简单复制的int k[1000]
也是如此。 但是您不需要它,因为线程不会更改数组/向量/列表本身而是元素。
你不需要。 从多个线程访问std::vector
是完全可以的,如果
因此,请确保创建一个大小为n=1000
的向量,并根据您的线程编号(1 到 4)将元素 0-249、250-499 等分配给您的线程。
所以你的每个线程都计算n/nthreads
元素。
原子可以用简单的可复制类型实例化。 Vector 不是这样的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.