Многопроцессорная обработка Python, не учитывающая LD_LIBRARY_PATH для динамической загрузки
Я работаю над проектом Python 3.5, который использует многопроцессорность, рабочий процесс должен иметь возможность вызывать скомпилированный код MATLAB. Чтобы не устанавливать переменную среды LD_LIBRARY_PATH перед запуском python (это вызывает конфликты с 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 не может выполнить эту настройку, что приводит к сбою при импорте. Я предполагаю, потому что динамический загрузчик не перечитывает переменную LD_LIBRARY_PATH после разветвления (это может быть правильно? Это не звучит правильно, но я не могу найти какую-либо документацию по этому поводу)
Есть ли способ сделать то, что я хочу, или что-то не так с моим кодом? Я должен отметить, что этот код работает нормально, если родительский процесс запущен с LD_LIBRARY_PATH=...
и что я убедился, что нет конфликтующих библиотек, которые могли бы испортить процесс.
1 ответ
Я предполагаю, потому что динамический загрузчик не перечитывает переменную LD_LIBRARY_PATH после разветвления
Это правда, к тому времени, когда вы звоните putenv
динамический компоновщик уже проанализирован LD_LIBRARY_PATH
и построил свои внутренние таблицы для разрешения символов. Вы не сможете восстановить те без exec
,
Кроме того, вы можете
- при запуске посмотрите, были ли заданы пути, а если нет, установите их и повторно
exec
сценарий - изменить рабочие сценарии на автономные, чтобы они могли быть
exec
скорее, чемfork
-ed - начните свое главное приложение с
LD_LIBRARY_PATH
задавать - вручную загрузить необходимые библиотеки через
dlopen
используя абсолютные пути