今天晚上考多核程序设计,其中有OpenMP的部分;早上刚刚研究出来以上数据私有化语句的用法,把我的理解贴出来分享了;由于一会儿还要去上课,时间不多,就挑重点的简单说一下了~
private子句用于将一个或多个变量声明成线程私有的变量,变量声明成私有变量后,指定每个线程都有它自己的变量私有副本,其他线程无法访问私有副本。即使在并行区域外有同名的共享变量,共享变量在并行区域内不起任何作用,并且并行区域内不会操作到外面的共享变量。
注意:用private子句声明的私有变量在并行区域的入口处是未初始化的,使用之前必须赋初值,否则编译运行时会报错 ;即并行区域内的变量与原同名变量没有任何关系,只是名字相同而已
实际中常常需要让private子句声明的私有变量继承同名变量的值,这时可以就可以在并行区域的入口处用firstprivate子句,告诉编译器用父线程的值初始化并行区域的子线程中的变量
类似地,lastprivate子句,如lastprivate(val)用来告诉编译器,把val在最后一个子线程中的值,拷回给父进程
下面举个例子,说明threadprivate和copyin的基本用法
int global=111;
#pragma omp threadprivate(global)
int _tmain(int argc, _TCHAR* argv[])
{
global=222;
#pragma omp parallel copyin(global) //
{
printf("Thread number %d global=%d\n",omp_get_thread_num(),global);
global=omp_get_thread_num()+10;
}
printf("global=%d\n",global);
printf("parallel again\n");
#pragma omp parallel
printf("Thread number %d global=%d\n",omp_get_thread_num(),global);
printf("global=%d\n",global);
return 0;
}
当环境变量 OMP_NUM_THREADS 设置为4时,运行结果类似于:(知道我为什么说“类似于”吧?各子线程的运行次序不是一定的)
threadprivate子句用来指定全局的对象被各个线程各自复制了一个私有的拷贝,即各个线程具有各自私有的全局对象。
用法如下:
#pragma omp threadprivate(list) new-line
threadprivate和private的区别在于:threadprivate声明的变量通常是全局范围内有效的,而private声明的变量只在它所属的并行构造中有效。
copyin子句用来将主线程中threadprivate变量的值拷贝到执行并行区域的各个线程的threadprivate变量中,便于线程可以访问主线程中的变量值,
用法如下:
copyin(list)
copyin中的参数必须被声明成threadprivate的,对于类类型的变量,必须带有明确的拷贝赋值操作符。
简单分析一下上面的例子:如果去掉copyin语句,则在第一个并行块中,只有主线程(即Thread number=0的线程)中的global的初始值为222,另外三个线程中,其值为全局的111,这就是threadprivate的作用
上面的并行块执行完之后,三个子进程并没有销毁,而是进入挂起状态。
下面的并行块没有使用copyin子句,这时打印出来的global的值,就是被唤醒的各线程中的值;中间和最后一行的global=10指的都是主线程中的值