通过共享对象的迭代是线程安全的吗? 我有一个并行的C++算法,看起来有点像: void recursiveFunction(int p,std::无序集localSet){ 向量toCall; 如果(p>SOMEINT){ 返回; } #计划(动态,1)共享的pragma omp并行(localSet,someGlobalVector,someOtherGlobalVector) 对于(int i=0;i
通过共享通过共享对象的迭代是线程安全的吗? 我有一个并行的C++算法,看起来有点像: void recursiveFunction(int p,std::无序集localSet){ 向量toCall; 如果(p>SOMEINT){ 返回; } #计划(动态,1)共享的pragma omp并行(localSet,someGlobalVector,someOtherGlobalVector) 对于(int i=0;i,c++,multithreading,parallel-processing,thread-safety,openmp,C++,Multithreading,Parallel Processing,Thread Safety,Openmp,通过共享无序集的迭代是否线程安全 通过共享无序集的迭代是线程安全的吗 不,根据定义,无序集不是线程安全的。然而,这并不一定意味着一个人的代码在使用这种结构时具有竞争条件;例如,如果只读取数据结构,即使是并发读取,那么就安全了。这就是为什么真正不可变的数据结构在定义上是线程安全的,因为人们无法修改这些结构,因此得名 另一方面,如果多个线程同时修改无序集,则其中一个线程具有竞争条件。尽管如此,只要在执行写操作时确保互斥,仍然可以以线程安全的方式写入无序的 非线程安全的数据结构(如无序集)依赖于访问它
无序集的迭代是否线程安全
通过共享无序集的迭代是线程安全的吗
不,根据定义,无序集
不是线程安全的。然而,这并不一定意味着一个人的代码在使用这种结构时具有竞争条件;例如,如果只读取数据结构,即使是并发读取,那么就安全了。这就是为什么真正不可变的数据结构在定义上是线程安全的,因为人们无法修改这些结构,因此得名
另一方面,如果多个线程同时修改无序集
,则其中一个线程具有竞争条件。尽管如此,只要在执行写操作时确保互斥,仍然可以以线程安全的方式写入无序的
非线程安全的数据结构(如无序集
)依赖于访问它们的代码,以确保当前由多个线程修改这些结构时的互斥性
为了避免竞争条件,可以使用OpenMP的critical
构造函数在insert
操作期间同步对共享结构的访问:
#pragma omp critical
{
// the code to insure mutual exclusion.
}
然而,由于这种同步机制的开销,这将减慢并行化的速度。或者,可以创建仅由每个线程单独访问的数据结构,插入到这些结构中,并让主线程将这些结构合并为一个(在并行区域之外)
让我们把你的代码分解一下:
void recursiveFunction(int p, std::unordered_set<int> localSet) {
#pragma omp parallel for schedule(dynamic, 1) shared(localSet, someGlobalVector, someOtherGlobalVector)
for (int i = 0; i < someGlobalVector[p].size(); ++i) {
auto someLocalValue = someGlobalVector[p][i];
auto someOtherLocal = someOtherGlobalVector[p][i];
std::unordered_set<int> filtered
for (auto elem : localSet) {
if (someLocalValue.count(elem) == 0) {
filtered.insert(elem)
}
}
}
}
通过共享无序集的迭代是线程安全的吗
不,根据定义,无序集
不是线程安全的。然而,这并不一定意味着一个人的代码在使用这种结构时具有竞争条件;例如,如果只读取数据结构,即使是并发读取,那么就安全了。这就是为什么真正不可变的数据结构在定义上是线程安全的,因为人们无法修改这些结构,因此得名
另一方面,如果多个线程同时修改无序集
,则其中一个线程具有竞争条件。尽管如此,只要在执行写操作时确保互斥,仍然可以以线程安全的方式写入无序的
非线程安全的数据结构(如无序集
)依赖于访问它们的代码,以确保当前由多个线程修改这些结构时的互斥性
为了避免竞争条件,可以使用OpenMP的critical
构造函数在insert
操作期间同步对共享结构的访问:
#pragma omp critical
{
// the code to insure mutual exclusion.
}
然而,由于这种同步机制的开销,这将减慢并行化的速度。或者,可以创建仅由每个线程单独访问的数据结构,插入到这些结构中,并让主线程将这些结构合并为一个(在并行区域之外)
让我们把你的代码分解一下:
void recursiveFunction(int p, std::unordered_set<int> localSet) {
#pragma omp parallel for schedule(dynamic, 1) shared(localSet, someGlobalVector, someOtherGlobalVector)
for (int i = 0; i < someGlobalVector[p].size(); ++i) {
auto someLocalValue = someGlobalVector[p][i];
auto someOtherLocal = someOtherGlobalVector[p][i];
std::unordered_set<int> filtered
for (auto elem : localSet) {
if (someLocalValue.count(elem) == 0) {
filtered.insert(elem)
}
}
}
}
如果全局对象是预填充的,并且只读取,那么是的,它通常是线程安全的。但是,如果共享对象可以在有人读取时进行修改,那么读取也就不是线程安全的。如果全局对象是预填充的,并且只在读取时进行,那么是的,它通常是线程安全的。但若在有人读取共享对象时可以修改它,那个么读取也就变得不线程安全了