private
变量没有初始化,即它们像任何其他本地自动变量一样以随机值开始(并且它们通常使用每个线程的堆栈上的自动变量来实现)。以这个简单的程序为例:
#include <stdio.h>
#include <omp.h>
int main (void)
{
int i = 10;
#pragma omp parallel private(i)
{
printf("thread %d: i = %d\n", omp_get_thread_num(), i);
i = 1000 + omp_get_thread_num();
}
printf("i = %d\n", i);
return 0;
}
如果有四个线程,它会输出类似以下内容的内容:
thread 0: i = 0
thread 3: i = 32717
thread 1: i = 32717
thread 2: i = 1
i = 10
(another run of the same program)
thread 2: i = 1
thread 1: i = 1
thread 0: i = 0
thread 3: i = 32657
i = 10
这清楚地表明了i
在并行区域内是随机的(未初始化),并且在并行区域之后对其进行的任何修改都是不可见的(即变量在进入该区域之前保持其值)。
If i
被制作firstprivate
,然后用并行区域之前的值进行初始化:
thread 2: i = 10
thread 0: i = 10
thread 3: i = 10
thread 1: i = 10
i = 10
仍对值进行修改i
并行区域内的内容在其之后不可见。
你已经知道了lastprivate
(它不适用于简单的演示程序,因为它缺乏工作共享结构)。
So yes, firstprivate
and lastprivate
只是特殊情况private
。第一个导致将值从外部上下文引入并行区域,而第二个将值从并行区域传输到外部上下文。这些数据共享类背后的基本原理是,并行区域内的所有私有变量都会隐藏外部上下文中的变量,即不可能使用赋值操作来修改外部值i
从平行区域内部。