我有这段代码:
#include <omp.h>
#include <stdio.h>
int main(){
int i,j = 0 ;
int tid;
# pragma omp parallel private(i,j,tid)
{
tid = omp_get_thread_num();
printf("Thread %d\n",tid);
for(i=0;i<10;i++){
# pragma omp for
for(j=0; j<10;j++){
tid = omp_get_thread_num();
printf("(i,j) = (%d,%d) Thread %d\n",i,j,tid);
}
}
}
return 0;
}
为什么第一个&#34; printf&#34;是由每个线程执行但不是第二个?
答案 0 :(得分:6)
&#34; omp parallel&#34;开始parallel region。当线程进入该区域时,通常会启动一组线程,线程进入成为主线程。然后团队中的所有线程执行代码,直到并行区域结束,线程连接回主线程。
因为omp parallel启动了一个并行区域,所以这就是你的private(i,j,tid)
go子句的子句,它定义了如何在区域内处理变量(默认,私有,共享,减少等)。并行区域开始的时间,以及可选择设置线程数的子句(num_threads)。
但是,通常有多个线程在并行区域执行完全相同的步骤并不是你想要的;您希望每个线程执行不同的任务,或者处理单独的某个问题。因此,OpenMP有worksharing constructs,包括&#34; omp for&#34;。在OpenMP for的情况下,循环迭代在线程之间分开,因此正好一个线程获得循环的每次迭代。 (为了实现这一点,循环本身就存在条件。)设置如何在线程之间分解for循环的子句 - (schedule,collapse),以及对迭代执行方式(有序)的限制,以及一些关于如何在for循环中处理变量的子句。 C中工作共享结构的其他示例是单一的 - 只有一个线程执行工作 - 任务和部分。
所以所有线程都执行第一个printf语句,因为团队中的所有线程都会命中它。但for循环迭代在线程之间分开,每个j只被一个线程打印出来。
如果你不需要在并行区域启动和for循环开始之间有任何代码,可以将两个指令组合为&#34; omp并行为&#34;,它们都启动并行区域并拆分(立即)跟随线程之间的循环。