Я действительно не уверен, чего вы здесь пытаетесь достичь ... На самом деле, без какой-либо работы, выполняемой другими потоками за пределами блока single
, я не вижу смысла в структуре.
В любом случае, я попытался немного экстраполировать и расширил ваш пример, добавив оператор printf()
за пределами блока, который также печатает значение a
, чтобы увидеть, как это передается в другие потоки. Более того, поскольку вы использовали директиву single
, я предположил, что вам нужен только один поток, выполняющий блок, даже если он находится в цикле while()
. Так что это выглядело очень хорошо подходящим для использования блокировок OpenMP ...
Вот что я придумал:
#include <stdio.h>
#include <omp.h>
#include <unistd.h>
int main() {
int a = 10;
bool finished = false;
omp_lock_t lock;
omp_init_lock( &lock );
#pragma omp parallel num_threads( 3 ) shared( a, finished )
{
while( !finished ) {
if ( omp_test_lock( &lock ) ) {
printf( "[%d] a is: %d\n", omp_get_thread_num(), a );
#pragma omp atomic update
a--;
usleep( 10 );
finished = true;
#pragma omp flush( finished )
omp_unset_lock( &lock );
}
#pragma omp flush( finished, a )
printf( "[%d] outside of if block, a is: %d\n", omp_get_thread_num(), a );
}
}
return 0;
}
Я добавил вызов usleep()
, чтобы немного задержать выполнение инструкций внутри блока if
и дать другим потокам возможность что-то напечатать. Я тестировал его с помощью gcc версий 4.9 и 5.3 и компилятора Intel 16.0, и все 3 дают мне одинаковый результат (очевидно, с некоторыми вариациями в порядке и количестве распечаток между запусками).
Результат выглядит так:
~/tmp$ icpc -fopenmp omplock.cc
~/tmp$ ./a.out
[0] a is: 10
[1] outside of if block, a is: 10
[1] outside of if block, a is: 9
[1] outside of if block, a is: 9
[1] outside of if block, a is: 9
[1] outside of if block, a is: 9
[1] outside of if block, a is: 9
[2] outside of if block, a is: 10
[1] outside of if block, a is: 9
[0] outside of if block, a is: 9
Отвечает ли этот подход вашим потребностям?
person
Gilles
schedule
24.02.2016