我正在使用一个使用多处理的python 3.5项目,工作进程需要能够调用已编译的MATLAB代码。为了不必在运行python之前设置LD_LIBRARY_PATH环境变量(它导致与libexpat冲突),我想只使用更改的LD_LIBRARY_PATH来处理此工作进程。我认为这样可以正常工作,因为使用fork()
创建的进程是在父进程中进行的任何环境更改时启动的。我正在使用
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)
在父进程中设置环境变量,然后在我有的工作进程中
def matlab_worker(matlab_pipe_end):
import service
service.initialize_stub()
崩溃,因为它无法正确找到库。如果我添加
,我可以看到环境变量设置正确def matlab_worker(matlab_pipe_end):
os.system('echo $LD_LIBRARY_PATH')
import service
service.initialize_stub()
设置变量,我甚至可以
def matlab_worker(matlab_pipe_end):
os.system('ldd <path>/service.so')
import service
service.initialize_stub()
并看到所有共享对象都已解析,但python无法遵守此设置,导致导入崩溃。我假设因为动态加载器在fork之后没有重新读取LD_LIBRARY_PATH变量(这可能是正确的吗?它听起来不正确但我找不到任何关于它的文档)
有没有办法做我想要的或我的代码有什么问题?我应该注意,如果使用LD_LIBRARY_PATH=...
启动父进程并且我确保没有冲突的库可能会搞砸该进程,则此代码可以正常工作。
答案 0 :(得分:1)
我假设因为动态加载器没有重新读取 fork之后的LD_LIBRARY_PATH变量
这是真的,当你调用putenv
动态链接器已经解析LD_LIBRARY_PATH
并构建它的内部表来解析符号时。如果没有exec
,您将无法重建那些。
或者,你可以
exec
脚本exec
- 而不是fork
- ed LD_LIBRARY_PATH
设置dlopen
手动加载所需的库