简体   繁体   English

Python多处理不支持LD_LIBRARY_PATH进行动态加载

[英]Python Multiprocessing not honoring LD_LIBRARY_PATH for dynamic loading

I am working on a python 3.5 project that uses multiprocessing, the worker process needs to be able to call compiled MATLAB code. 我正在使用多处理的python 3.5项目上工作,工作进程需要能够调用已编译的MATLAB代码。 In order to not have to set the LD_LIBRARY_PATH environment variable before running python (it causes conflicts with libexpat), I want to have only this worker process using the altered LD_LIBRARY_PATH. 为了不必在运行python之前设置LD_LIBRARY_PATH环境变量(这会导致与libexpat冲突),我希望仅使用更改后的LD_LIBRARY_PATH的此工作进程。 I figured this would work fine since processes created with fork() are started with any environment changes made in the parent. 我认为这可以正常工作,因为使用fork()创建的进程是在父级中进行的任何环境更改下启动的。 I am using 我在用

matlab_runtime_paths = [
    '/usr/local/MATLAB/MATLAB_Runtime/v91/runtime/glnxa64',
    '/usr/local/MATLAB/MATLAB_Runtime/v91/bin/glnxa64',
    '/usr/local/MATLAB/MATLAB_Runtime/v91/sys/os/glnxa64',
    '/usr/local/MATLAB/MATLAB_Runtime/v91/sys/opengl/lib/glnxa64'
]
system_lib_dir = '{}/lib'.format(sys.prefix)

lib_paths = matlab_runtime_paths + [system_lib_dir]
lib_paths_format = ':'.join(lib_paths)
os.putenv('LD_LIBRARY_PATH', lib_paths_format)

to set the environment variable in parent process, then later in the worker process I have 在父进程中设置环境变量,然后在工作进程中

def matlab_worker(matlab_pipe_end):
    import service
    service.initialize_stub()

which crashes because it is unable to find the library properly. 由于无法正确找到库而崩溃。 I can see that the environment variable is being set correct, if I add 如果添加,我可以看到环境变量设置正确

def matlab_worker(matlab_pipe_end):
    os.system('echo $LD_LIBRARY_PATH')
    import service
    service.initialize_stub()

the variable is set, I can even do 设置了变量,我什至可以做

def matlab_worker(matlab_pipe_end):
    os.system('ldd <path>/service.so')
    import service
    service.initialize_stub()

and see that all shared objects are resolved, yet python fails to honor this setting, crashing on the import. 并看到所有共享库均已解决,但是python无法使用此设置,导致导入时崩溃。 I'm assuming because the dynamic loader doesnt re-read the LD_LIBRARY_PATH variable after a fork (can that be correct? It doesnt sound correct but I cant find any documentation about it) 我假设是因为动态加载程序在分叉后没有重新读取LD_LIBRARY_PATH变量(可以吗?听起来不正确,但是我找不到任何有关它的文档)

Is there any way to do what I want or is there something wrong with my code? 有什么方法可以做我想要的,还是我的代码有问题? I should note that this code works fine if the parent process is launched with LD_LIBRARY_PATH=... and that I have made sure there are no conflicting libraries that could be screwing up the process. 我应该注意,如果使用LD_LIBRARY_PATH=...启动父进程,则此代码可以正常工作,并且我已确保没有冲突的库可能会破坏进程。

I'm assuming because the dynamic loader doesnt re-read the LD_LIBRARY_PATH variable after a fork 我假设是因为动态加载程序在分叉后不会重新读取LD_LIBRARY_PATH变量

That's true, by the time you call putenv dynamic linker has already parsed LD_LIBRARY_PATH and built it's internal tables for resolving symbols. 是的,到您调用putenv动态链接器时,它已经解析了LD_LIBRARY_PATH并建立了用于解析符号的内部表。 You won't be able to rebuild those without exec . 没有exec您将无法重建它们。

Alternatively, you can 或者,您可以

  • at startup, see if paths have been set and if they haven't, set them and re- exec the script 在启动时,查看是否已设置路径,如果尚未设置,请设置路径并重新exec脚本
  • change worker scripts to be standalone so that they can be exec -ed rather than fork -ed 将工作程序脚本更改为独立脚本,以便可以exec而不是fork -ed
  • start your main app with LD_LIBRARY_PATH set 使用设置的LD_LIBRARY_PATH启动您的主应用
  • manually load needed libraries via dlopen , using absolute paths 使用绝对路径通过dlopen手动加载所需的库

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM