OpenMP - 锁定 - 死锁

时间:2018-02-20 16:08:25

标签: c openmp

我最近遇到了以下OpenMP死锁代码。但我无法理解这种情况。但我发现在第二个omp部分,如果我们使用locka然后lockb将没有死锁。任何人都可以帮助我理解这一点。

#pragma omp parallel shared(a, b, nthreads, locka, lockb)
  #pragma omp sections nowait
    {
    #pragma omp section
      {
      omp_set_lock(&locka);
      for (i=0; i<N; i++)
        a[i] = ..

      omp_set_lock(&lockb);
      for (i=0; i<N; i++)
        b[i] = .. a[i] ..
      omp_unset_lock(&lockb);
      omp_unset_lock(&locka);
      }

    #pragma omp section
      {
      omp_set_lock(&lockb);
      for (i=0; i<N; i++)
        b[i] = ...

      omp_set_lock(&locka);
      for (i=0; i<N; i++)
        a[i] = .. b[i] ..
      omp_unset_lock(&locka);
      omp_unset_lock(&lockb);
      }
    }  /* end of sections */
  }  /* end of parallel region */

1 个答案:

答案 0 :(得分:1)

这很简单。如果第一个线程锁定locka和第二个线程锁lockb,则会发生死锁。接下来会发生什么?

第一个线程想要锁定lockb。但是,lockb被第二个线程锁定,因此第一个线程被阻止并等待解锁lockb

同样,第二个线程想要锁定locka。但是,locka被第一个线程锁定,因此第二个线程被阻止并等待解锁locka

因此,两个线程都处于阻塞状态并且都等待解锁,这种情况从未发生过,因为解锁代码位于线程被阻塞的行之下。

如果在第二个section中,locka被锁定,则情况会有所不同。两个线程首先尝试锁定locka。但是,只允许一个线程成功;这是由OpenMP库保证的。因此,只有一个线程(A)锁定locka而另一个线程(B)被阻塞,并等待locka解锁。

然后

线程A执行其代码,因为它没有被阻止。当它最终解锁locka时,线程B被解锁。

在这种情况下,死锁意味着两个线程都处于阻塞状态,并等待彼此执行某些操作以解除阻塞。在第一种情况下,确实会发生这种情况,在第二种情况下,它可以发生。