2.7.1 threadprivate Directive
The threadprivate
directive makes the named file-scope, namespace-scope, or static block-scope variables specified in the variable-list private to a thread. variable-list is a comma-separated list of variables that do not have an incomplete type. The syntax of the threadprivate
directive is as follows:
#pragma omp threadprivate
(variable-list) new-line
Each copy of a threadprivate
variable is initialized once, at an unspecified point in the program prior to the first reference to that copy, and in the usual manner (i.e., as the master copy would be initialized in a serial execution of the program). Note that if an object is referenced in an explicit initializer of a threadprivate
variable, and the value of the object is modified prior to the first reference to a copy of the variable, then the behavior is unspecified.
As with any private variable, a thread must not reference another thread's copy of a threadprivate
object. During serial regions and master regions of the program, references will be to the master thread's copy of the object.
After the first parallel region executes, the data in the threadprivate
objects is guaranteed to persist only if the dynamic threads mechanism has been disabled and if the number of threads remains unchanged for all parallel regions.
The restrictions to the threadprivate
directive are as follows:
A
threadprivate
directive for file-scope or namespace-scope variables must appear outside any definition or declaration, and must lexically precede all references to any of the variables in its list.Each variable in the variable-list of a
threadprivate
directive at file or namespace scope must refer to a variable declaration at file or namespace scope that lexically precedes the directive.A
threadprivate
directive for static block-scope variables must appear in the scope of the variable and not in a nested scope. The directive must lexically precede all references to any of the variables in its list.Each variable in the variable-list of a
threadprivate
directive in block scope must refer to a variable declaration in the same scope that lexically precedes the directive. The variable declaration must use the static storage-class specifier.If a variable is specified in a
threadprivate
directive in one translation unit, it must be specified in athreadprivate
directive in every translation unit in which it is declared.A
threadprivate
variable must not appear in any clause except thecopyin
,copyprivate
,schedule
,num_threads
, or the if clause.The address of a
threadprivate
variable is not an address constant.A
threadprivate
variable must not have an incomplete type or a reference type.A
threadprivate
variable with non-POD class type must have an accessible, unambiguous copy constructor if it is declared with an explicit initializer.
The following example illustrates how modifying a variable that appears in an initializer can cause unspecified behavior, and also how to avoid this problem by using an auxiliary object and a copy-constructor.
int x = 1;
T a(x);
const T b_aux(x); /* Capture value of x = 1 */
T b(b_aux);
#pragma omp threadprivate(a, b)
void f(int n) {
x++;
#pragma omp parallel for
/* In each thread:
* Object a is constructed from x (with value 1 or 2?)
* Object b is copy-constructed from b_aux
*/
for (int i=0; i<n; i++) {
g(a, b); /* Value of a is unspecified. */
}
}
Cross References:
Dynamic threads, see Section 3.1.7 on page 39.
OMP_DYNAMIC
environment variable, see Section 4.3 on page 49.