我有一个需要执行的函数n=1000
次。此函数执行蒙特卡罗风格模拟并返回 int
作为结果。我想运行 nthreads=4
在平行下。每当一个线程完成一个循环时,它应该将结果放在 std::vector<int>
中。 .
因此,经过 1000 个循环后,我的 vector 为 1000 int
可以通过统计来检验。
自从 std::vector
不是线程安全的,我想到了std::mutex
(这肯定会奏效)。
但我想知道我是否可以将 vector 声明为原子的,从而绕过互斥锁?
是否有可能拥有 std::atomic<std::vector<int>>
?我可以使用 push_back
等等?
最佳答案
C++11 §29.5/1 说
There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9).
平凡可复制是什么意思?
§3.9 告诉
Scalar types, trivially copyable class types (Clause 9), arrays of such types, and cv-qualified versions of these types (3.9.3) are collectively called trivially copyable types.
对于类类型(std::vector
是):
A trivially copyable class is a class that:
- has no non-trivial copy constructors
- has no non-trivial move constructors
- has no non-trivial copy assignment operators
- has no non-trivial move assignment operators
- has a trivial destructor
根据此列表std::vector
不可轻易复制,因此您不能使用 std::atomic<std::vector<int>>
.
由于您事先知道大小,并且您不需要使用需要将 vector 重新分配到不同位置的方法(例如 push_back)
。您可以使用 std::vector<int>::resize
或大小构造函数进行预分配和预构造所需的 int
s。因此,您的并发线程不需要对 vector 本身进行操作,而是对元素进行操作。
如果不同线程无法访问同一元素,则不存在竞争条件。
int k[1000]
也是如此这很容易复制。但您不需要这样做,因为线程不会更改数组/vector/列表本身,而是更改元素。
关于c++ - 我可以制作一个线程安全的 std::atomic<vector<int>> 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32694114/