使用omp_set_lock的OpenMP死锁

问题描述 投票:0回答:1

我具有一个具有以下常规结构的函数:

void a_generic_function(int N, int *arr, int *superarr)
{
  //some code
  for (int i = 0; i < N; i++)
  {
    omp_init_lock(&(lock[i])); //Initializes N locks, lock is allocated dynamic mem previously.
  }
  #pragma omp parallel shared(lock)
  {
    #pragma omp for
    {
      for (int i = 1; i <= N; i++)
      {
        //some code
        for (int j = arr[i-1]; j < arr[i]; i++) //where arr is size N+1
        {
          //some code
          for (int k = 0; k < temp; k++) //where temp < N
          {
            omp_set_lock(&(lock[subarr[k]])); //subarr is size <= N
            superarr[subarr[k]] += temp-1; //superarr is size = N. Temp is an int value.
            omp_unset_lock(&(lock[subarr[k]]));
          }
        }
      }
    }
  }
}

此代码中只有一点,对线程的输入有限制,应在关键操作完成后立即将其解锁,但此功能通常会死锁。我不明白是什么原因造成的。

(出于完整性考虑:此函数之外没有并行化)

c locking openmp deadlock
1个回答
0
投票

肯定有太多“ //一些代码”,但是对我来说,问题是您没有释放设置的相同锁,即,在调用subarr[k]之后和[C0之前,omp_set_lock的值发生了变化]。一种可能的解决方案是制作一个线程专用变量,例如

omp_unset_lock

这将确保线程释放与其设置的相同的锁。

作为奖励:您可以安全地将int n = subarr[k]; omp_set_lock(&lock[n]); // do stuff omp_unset_lock(&(lock[n])); 放在锁定初始化循环中,以提高性能。

© www.soinside.com 2019 - 2024. All rights reserved.