在Openmp中销毁线程(C++)
问题描述:
是否可以销毁由OpenMP创建的线程?程序启动时,只有一个线程。由于有一个线程池,并行化部分之后保留多个线程。平行部分运行后,有没有办法销毁这个池?在Openmp中销毁线程(C++)
我问,因为我在动态库中使用OpenMP,并且在线程正在运行时程序库句柄不能关闭(程序会出现段错误)。
感谢
更多的解释: 我把所有的并行代码到模块(共享库)。然后我加载模块并将它传递给派生自抽象基类的类。该模块然后'并行运行'该类。这样,我就可以不使用并行化,OpenMP,MPI或其他任何方法,并且可以在运行时甚至在运行时更改并行方案。但是OpenMP不会销毁线程,并且当需要手动dlclose库时,它会发生段错误,因为资源从线程下面销毁(我相信)。让程序在没有关闭库的情况下完成,现在可能就可以了,但是想要手动关闭库可能还是会在将来出现(想想即将改变的方案)。希望这是有道理:)谢谢
答
在这个时候,OpenMP规范并没有给予用户任何控制线程被销毁的能力。你所说的非常有趣,在任何OpenMP语言委员会会议期间都没有提出讨论该规范。你能提供更多关于你在做什么和问题是什么的信息吗?将这个讨论提交给委员会会有帮助。
编辑加入3/7 -
好了 - 这里是,似乎工作一个简单的例子,它可能会得到解决您的问题:
$> cat prog.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(void)
{
void (*f)(void);
void *handle;
handle = dlopen("./shared.so", RTLD_NOW);
if (!handle) {
printf("*** dlopen error - %s\n", dlerror());
abort();
}
f = dlsym(handle, "foo");
if (!f) {
printf("*** dlsym error - %s\n", dlerror());
abort();
}
f();
if(dlclose(handle)) {
printf("*** dlclose error - %s\n", dlerror());
abort();
}
return 0;
}
$> cat shared.c
#include <omp.h>
#include <stdio.h>
void foo(void)
{
int i;
puts("... in foo\n");
#pragma omp parallel for
for (i=0; i<10; i++)
printf("t#: %i i: %i\n", omp_get_thread_num(), i);
puts("... exiting foo");
}
$> gcc -rdynamic -fopenmp prog.c -ldl -o prog
$> gcc -c -fopenmp -fPIC -o shared.o shared.c
$> ld -shared -o shared.so shared.o
$> ./prog
... in foo
t#: 2 i: 4
t#: 2 i: 5
t#: 3 i: 6
t#: 3 i: 7
t#: 0 i: 0
t#: 0 i: 1
t#: 4 i: 8
t#: 4 i: 9
t#: 1 i: 2
t#: 1 i: 3
... exiting foo
虽然没有OpenMP的代码在主程序(prog.c),我使用-fopenmp标志编译它。这意味着OpenMP环境将在调用实际使用OpenMP的共享库之前设置。这似乎解决了执行dlclose的问题,因为环境仍然存在。它还允许首次使用OpenMP获得的线程留待后续使用。这是否适用于解决您的问题(或者这只适用于这个简单的例子)?
是的,环顾四周我根本没有看到任何方法 - 只是OpenMP自动处理创建/销毁。我附加了我的问题,提供更多信息供您阅读。 :) BP – 2011-03-05 03:46:43
谢谢你的解释。到目前为止,在程序结束之前将图书馆开放并不是一个问题。我认为你是对的,但这可能是一个问题,委员会应该考虑以某种方式关闭OpenMP。 – ejd 2011-03-07 15:17:41
经过一段时间的调查,我认为问题实际上是在GDB。主程序是线程不可知的,但似乎自行工作。在GDB下(不得不预装libpthread)它崩溃。我尝试了您的建议,并将主程序与OpenMP关联,现在它确实在GDB下运行。所以也许有点诟病OpenMP; GDB对图书馆的处理可能是真的可以责备的。感谢您的输入:) BP – 2011-03-10 20:09:32