OpenMP 3.0 では、ロックはスレッドではなく、タスクに所有されていると規定されています。ロックが取得されると、現在のタスクがそれを所有します。タスクの終了時には、同じタスクがそのロックを解放する必要があります。
一方、critical コンストラクトは、スレッドベースの相互排他機構として残されています。
ロックの所有者の変更により、ロックを使用する際にはより慎重な処理が必要となります。次のプログラム (OpenMP 仕様のバージョン 3.0 の例 A.43.1c として紹介されています) は OpenMP 2.5 に適合しています。これは、並列領域にあるロック lck を解放するスレッドは、プログラムの順次処理部分で使用されるそのロックを取得したのと同じスレッドであるためです (並列領域のマスタースレッドと初期のスレッドが同一)。ところが、このプログラムは OpenMP 3.0 では適合しません。これは、ロック lck を解放するタスク領域が、ロックを取得したタスク領域と異なるためです。
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
int main()
{
int x;
omp_lock_t lck;
omp_init_lock (&lck);
omp_set_lock (&lck);
x = 0;
#pragma omp parallel shared (x)
{
#pragma omp master
{
x = x + 1;
omp_unset_lock (&lck);
}
}
omp_destroy_lock (&lck);
}
|