【发布时间】:2016-12-16 20:24:19
【问题描述】:
我必须创建一个包含 k 个元素的向量。每个线程都会创建它的部分,比如说 k * 25%,并且必须将它放入向量中的任何索引处。在example 的驱使下,我正准备做这样的事情:
std::atomic<std::vector<aClass<templatedType>>> H;
但这不起作用:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/atomic:823:13: error:
_Atomic cannot be applied to type
'std::__1::vector<StableHashFunction<int>,
std::__1::allocator<StableHashFunction<int> > >' which is not trivially
copyable
mutable _Atomic(_Tp) __a_;
因为它不是简单可复制的——而且解决方法也不是很好。此外,我需要它是原子的吗?
这就是问题,当我不关心顺序时,我还应该使用原子吗?换句话说,数据竞争是否只影响元素的顺序,或者它们会导致其他副作用,比如躲避一个元素(所以最后只有 k - 1 个元素而不是 k 个元素)?
【问题讨论】:
-
push_back()或emplace_back()不是原子操作,因此您必须使用诸如std::mutex之类的同步机制来保护它们。 -
创建一个大小为 K 的向量,然后每个线程更新该向量的一部分,这样就不会在线程之间共享数据。
-
@Jarod42 这也是我的第一个想法,但要做到这一点,您需要默认构造向量中的所有元素。
-
@gsamaras 好吧,如果你按照我的建议去做,那么只有在 CPU 密集型工作来计算应该用于初始化向量的值时才有意义。别担心,我只是很少投赞成票;)。
-
顺便说一句,@πάνταῥεῖ 不是关于互斥锁的回答...如果您需要将工作负载分成不同的线程,那么您可能关心性能。如果你关心性能,你应该尽可能多地编写每个并行化,尽可能少互斥/原子少/共享内存,因为线程之间的同步非常昂贵,你可能会浪费掉通过运行节省的所有时间在平行下。所以只要你的向量计算在线程之间是独立的,确保目标内存也是,那么你就不需要任何锁定和同步,只需要等待所有线程完成+合并结果。
标签: c++ multithreading stl parallel-processing stdthread