Директива SINGLE применяется, когда внутри параллельной области требуется выделить блок кода, который должен быть выполнен только одной нитью.
C/C++:
#pragma omp single [ ключ [ ключ ] ... ] new-line
Блок
Fortran:
!$OMP SINGLE[ ключ [ [ , ] ключ ] ... ]
Блок
!$OMP END SINGLE [ nowait ]
Список ключей:
PRIVATE (list)
FIRSTPRIVATE (list)
NOWAIT (в языке C/C++)
Участок кода будет выполнен той нитью, которая первой дойдет до данной точки программы. Приведем пример программы.
Программа single.c
#include <stdio.h> #include <stdlib.h> #include <omp.h> int main() { int i, n = 9; int a, b[n]; omp_set_num_threads(4); /* Функция omp_set_num_threads задает количество нитей в параллельном регионе.*/ for (i=0; i<n; i++) b[i] = -1; #pragma omp parallel shared(a,b) private(i) { #pragma omp single nowait { a = 10; printf("Код исполняется нитью %d\n", omp_get_thread_num()); /* Функция omp_get_thread_num() определяет номер вызвавшей ее нити */ } #pragma omp for for (i=0; i<n; i++) b[i] = a; } printf("В основном потоке\n"); for (i=0; i<n; i++) printf("b[%d] = %d\n",i,b[i]); return(0); }
Программа single.f
program single integer i, n, a, b(10) integer omp_get_thread_num n = 10 call omp_set_num_threads(4) do i = 1, n b(i) = -1 end do !$OMP PARALLEL SHARED(a,b) PRIVATE(i) !$OMP SINGLE a = 10 write (*,11) omp_get_thread_num() !$OMP END SINGLE NOWAIT !$OMP DO do i = 1, n b(i) = a end do !$OMP END DO !$OMP END PARALLEL print *, 'Main stream' do i = 1, n write(*,10) i, b(i) end do 10 format(2x, 'b(',i2,')=',I2) 11 format(x, 'Thread number =',I2) end