在OpenMP中将结构指针定义为threadprivate

时间:2016-08-11 02:15:47

标签: c multithreading pointers struct openmp

从C我调用一段Fortran代码,然后调用其他一些C代码。为了调用C代码的最后一位,我需要有两个指向EarthModel结构的全局指针和一个我定义的SurveyGeometry结构。我试图在calcGreen.c中并行化下面的for循环,但是使用多个线程(程序段错误)已经失败了。

我需要每个线程都有自己的指针,指向不同的EarthModels和SurveyGeometrys,同时保持全局定义。我尝试使用omp threadprivate指令为每个线程提供自己的结构指针,它可以在线程级别分配和释放并维护全局定义。我还读过创建的线程的默认堆栈是2M,所以我尝试通过使用export OMP_STACKSIZE = 512M(和更高版本)设置环境变量来为线程提供更多内存,但是segfault仍然存在。

shared.h

extern EarthModel *g_em;
extern SurveyGeometry *g_sg;
#pragma omp thradprivate(g_em, g_sg)

util.h

#include "shared.h"

EarthModel *g_em;
SurveyGeometry *g_sg;

calcGreen.c

#include "util.h"

...
omp_set_num_threads(2);
#pragma omp parallel for schedule(dynamic,1)
for(int ii=0; ii<nseg; ++ii){
  for(int jj=0; jj<nseg; ++jj){
    ...
    // code to allocate and initialize g_sg and g_em
    g_sg = initSG();
    g_em = initEM();
    // code to pass through to Fortran and execute C function on g_sg and g_em
    // code to free g_sg and g_em
    freeSG(g_sg);
    freeEM(g_em);
    ...
  }
}
...

编辑:或者,有没有办法从第一个C函数获取结构g_sg和g_em,其中分配并设置为Fortran以线程安全方式调用的C函数而不使用全局变量?

2 个答案:

答案 0 :(得分:1)

不完全确定为什么会这样,但拼写&#34; threadprivate&#34;正确地将#pragma omp threadprivate指令移动到util.h似乎已经成功了。第一个并不令人惊讶,但第二个对我来说并不直观。感谢您的帮助。

答案 1 :(得分:0)

如果Harald的评论尚未解决问题,可以提出一些建议:

1)如果允许更改calcGreen.c的源代码,并且每个线程在通过调用initSG()和initEM进行(重新?)分配和(重新?)初始化之前不使用指针(),我会将它们声明为内部for循环中的局部变量。

2)initSG(),initEM(),freeSG()和freeEM()的实现是线程安全的还是可重入的?