繁体   English   中英

我可以创建一个线程安全的 std::atomic <vector<int> &gt;?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM