Python 导入失败并显示“dlopen:无法使用静态 TLS 加载更多对象”

Cal*_*ior 5 python cython dlopen pycaffe

我编写了一个调用的多线程模块fast_nnCython并使用以下内容编译它setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy

setup(
    ext_modules = cythonize([
        Extension("fast_nn", ["fast_nn.pyx"], language = 'c++', extra_compile_args = ['-O3', '-fopenmp'], extra_link_args = ['-fopenmp'], include_dirs = [numpy.get_include()])
    ])
)
Run Code Online (Sandbox Code Playgroud)

另外,我使用了caffe框架的python 绑定。

如果我单独或pycaffe单独使用我的模块,一切都很好。但是,以下组合是有问题的:

import caffe.io
import fast_nn
Run Code Online (Sandbox Code Playgroud)

在一台机器上,它不会导致任何问题。在另一台机器上,我收到以下异常:

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    import fast_nn
ImportError: dlopen: cannot load any more object with static TLS
Run Code Online (Sandbox Code Playgroud)

这个线程我了解到有太多带有初始执行静态 TLS 的库已被动态加载。但是我能做些什么来解决这个问题呢?有什么方法可以在禁用静态 TLS 的情况下编译我的模块或更好的解决方案吗?

但是, 的输出readelf -a fast_nn.cpython-35m-x86_64-linux-gnu.so | grep TLS在我的库中没有显示任何 TLS 符号。但是一些依赖库包含这样的符号。


到目前为止尝试的解决方案

更改两次导入的顺序(即caffe在我的cython模块之后导入)解决了问题。但是,由于我的实际情况要复杂得多,而且这两个模块都是从其他导入间接导入的,因此我无法更改导入顺序。

同样,将我编译的模块库的路径导出到LD_PRELOAD也有同样的效果,但也不是一个优雅的解决方案。