从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函数而不使用全局变量?
答案 0 :(得分:1)
不完全确定为什么会这样,但拼写&#34; threadprivate&#34;正确地将#pragma omp threadprivate指令移动到util.h似乎已经成功了。第一个并不令人惊讶,但第二个对我来说并不直观。感谢您的帮助。
答案 1 :(得分:0)
如果Harald的评论尚未解决问题,可以提出一些建议:
1)如果允许更改calcGreen.c的源代码,并且每个线程在通过调用initSG()和initEM进行(重新?)分配和(重新?)初始化之前不使用指针(),我会将它们声明为内部for循环中的局部变量。
2)initSG(),initEM(),freeSG()和freeEM()的实现是线程安全的还是可重入的?