修改OpenMP并行区域内的函数的局部静态变量:竞争条件?

时间:2018-02-24 03:19:11

标签: c++ openmp

我正在处理一个令人困惑的代码库,我有这样的情况。

#pragma omp parallel for 
for ( int i = 0; i < N; i++) {
  problemFunction();
}

void problemFunction() {

  static bool inFunction;
  if ( inFunction == true ) {
    return;
  }
  else {
    inFunction = true;
  }
}

这会造成竞争条件吗?

2 个答案:

答案 0 :(得分:2)

与通常驻留在线程堆栈(私有)上的自动局部变量不同,具有静态存储类的局部变量驻留在进程的数据段中,因此在执行给定函数的所有线程之间共享,因此,您的代码包含竞争条件。要阻止共享,您应该使用OpenMP的threadprivate构造:

void problemFunction() {
  static bool inFunction;
  #pragma omp threadprivate(inFunction)

  if ( inFunction == true ) {
    return;
  }
  else {
    inFunction = true;
  }
}

这将改变变量存储在数据段中的位置到所谓的线程局部存储(TLS)。保留原始static语义,即在函数调用之间保留值,但现在每个线程都有自己的副本。在{/ em>变量声明之后,threadprivate构造应始终

答案 1 :(得分:0)

是的,这会导致比赛执行(显然)。为避免这种情况,您可以使用thread_local (see also here)变量(此外,您的函数似乎也不必复杂):

void problemFunction() {
  static thread_local bool inFunction;
  inFunction = true;
}

当每个线程都有自己的变量inFunction时。这样,您的函数可以与任何线程实现一起使用,而不仅仅是OpenMP。