在从动态库加载的函数中使用OpenMP时出错
Tricky error using OpenMP in function loaded from dynamic libraries
我的问题涉及在动态库中存储的C++函数中使用OpenMP。让我们考虑以下代码(在shared.cpp中):
#include "omp.h"
#include <iostream>
extern "C" {
int test() {
int N = omp_get_max_threads();
#pragma omp parallel num_threads(N)
{
std::cout << omp_get_thread_num() << std::endl;
}
return 0;
}
};
我使用g++编译此代码:g++-fopenmp-shared-fPIC-o shared.so shared.cpp。然后,要使用测试函数,我有以下程序(main.cpp):
#include <iostream>
#include <dlfcn.h>
int main() {
void* handle = dlopen("./shared.so", RTLD_NOW);
if (!handle) {
std::cerr << "can not open shared.so" << std::endl;
return 1;
}
int(*f)() = (int(*)()) dlsym(handle,"test");
if (!f) {
std::cerr << "can not find 'test' symbol in shared.so" << std::endl;
return 1;
}
(*f)();
if (dlclose(handle)) {
std::cerr << "can not close shared.so" << std::endl;
return 1;
}
return 0;
}
使用命令编译:g++-o main main.cpp-ldl问题是分段错误发生在程序执行的最后。根据valgrind的说法,一些线程在这一点上仍然是活动的,这似乎与OpenMP的行为一致。
这篇文章中的一个解决方案(针对C代码)是使用gcc-fopenmp标志编译程序,但g++似乎足够聪明,可以检测到该程序中从未使用过OpenMP,也从未加载过OpenMP环境(两个版本的汇编代码相等)。我找到的唯一解决方法是在程序中对OpenMP进行无用的调用,这将迫使g++加载OpenMP环境,然后执行就正确了。但对我来说,这种变通方法相当丑陋。我试过g++-4.8.2、g++-4.8.1、g++-4-7.3和g++-4.6.4。(对于icc-14,在程序中使用-openmp选项实际上可以解决问题)。
有人遇到过这个问题吗?有更清洁的解决方法吗?谢谢Thomas
编辑尝试使用G++-4.9.2:仍然失败
我认为您看到了GCC的OpenMP运行库libgomp的问题。尝试与它链接:g++-o main main.cpp-ldl-lcomp,您的segfault就会消失。
libgomp有一些在第一次OpenMP调用时初始化的内部状态。由于某些原因,如果动态加载OpenMP库,则不会发生取消初始化的情况。对我来说这听起来像个bug。
英特尔编译器有自己的OpenMP运行时(libomp5),它没有这个问题。
我遇到了一个非常类似的问题,这是由于使用了带有RTLD_LAZY | RTLD_GLOBAL
标志的dlopen
。将RTLD_LAZY
替换为RTLD_NOW
使其能够工作。
对于以上问题,我建议尝试RTLD_NOW | RTLD_GLOBAL
。
- 访问者访问变体并返回不同类型时出错
- 在Linux for Windows上编译C++代码时出错
- 读取文件的最后一行并输入到链接列表时出错
- OpenMP阵列性能较差
- 重载操作程序时出错>>用于类中的字符串 memebr
- 调用专用模板时出错"no matching function for call to [...]"
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 在Google Kick start中提交时出错
- 在c++中访问int到类对象的映射时出错
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 分段错误当我试图运行程序时出错
- 使用dynamic_cast和构造函数时出错
- C++ 使用 OpenMP 时,如果 for 循环在 if else 语句中出错
- 当我在 C++ 中使用 OpenMp 的折叠时出错
- 从 OpenMP 循环内部访问和编辑 Qmap 时出错
- 在从动态库加载的函数中使用OpenMP时出错
- 启用 openmp 时出错 - "ld: library not found for -lgomp" 和 Clang 错误
- 嵌套 for 循环的 openmp 出错