Использование многопроцессорности в Python версиях - PullRequest
1 голос
/ 08 мая 2020

Мне было интересно, могу ли я использовать многопроцессорность для запуска кода Python 2.7 изнутри Python 3.7, поскольку он все равно порождает новый интерпретатор. Следующий код (try_multiproc.py), кажется, отлично работает с любым интерпретатором Python 2.7:

import multiprocessing

def foo():
    print('foo')

if __name__ == '__main__':
    ipath = r"C:\miniconda3\envs\py2env\python.exe"  # path to Python 2.7 interpreter in a conda env
    multiprocessing.set_executable(ipath)
    p = multiprocessing.Process(target=foo)
    p.start()

Однако, когда я пытаюсь запустить его под интерпретатором Python 3.7, я получаю:

$ python try_multiproc.py
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named spawn

Пытаюсь ли я сделать что-то принципиально невозможное, или это связано с некоторыми проблемами в моей среде conda? (Однако, как отмечалось выше, похоже, он отлично работает в средах 2.7).

1 Ответ

0 голосов
/ 13 июля 2020

Я столкнулся с той же проблемой и немного покопался, к сожалению, это невозможно сделать.

multiprocessing.spawn.get_command_line устанавливает код для исполняемого файла на запустить. Это будет выглядеть примерно так:

["python2.exe" "-c" "from multiprocessing.spawn import spawn_main; spawn_main(parent_pid=16524, pipe_handle=496)" "--multiprocessing-fork"]

Поскольку multiprocessing.spawn был переименован из multiprocessing.forking, указанная выше строка не будет понятна Python 2. Я попытался создать фиктивную spawn.py file, где spawn_main вызывает forking.main, но затем я начал получать плохие ошибки файлового дескриптора, и, поскольку класс невероятно сложен, не стоит прилагать усилия для отладки.

Получить эту работу было чрезвычайно сложно. В итоге я использовал subprocessing для создания другого процесса python, и мне пришлось передать путь импорта модуля и имя функции для выполнения. Работа с stderr затруднительна, поскольку не каждая «ошибка» является исключением, поэтому требовалось немного взломанного кода, чтобы определить, нужно ли повторно вызывать ошибку или игнорировать ее. Наконец, мне пришлось распечатать результат подпроцесса в кодировке base64, взять и декодировать его из stdout, а все остальное распечатать.

...