[英]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 或者,您可以
exec
the script 在启动时,查看是否已设置路径,如果尚未设置,请设置路径并重新exec
脚本 exec
-ed rather than fork
-ed 将工作程序脚本更改为独立脚本,以便可以exec
而不是fork
-ed LD_LIBRARY_PATH
set 使用设置的LD_LIBRARY_PATH
启动您的主应用 dlopen
, using absolute paths 使用绝对路径通过dlopen
手动加载所需的库
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.