Ubuntu, cx_Freeze и multiprocessing.Manager () конфликтуют в случае процессов типа «порождение» - PullRequest
7 голосов
/ 14 февраля 2020

Конверт:

Ubuntu - 18.04
Python - 3.6.6
cx_Freeze - 6.1

Код:

Простой main_script. Файл py (пример в репозитории - https://github.com/Yuriy-Leonov/cython_multiprocessing_issue)

import multiprocessing

if __name__ == '__main__':
    print("step-1")
    multiprocessing.set_start_method("spawn")
    print("step-2")
    multiprocessing.freeze_support()
    print("step-3")
    manager = multiprocessing.Manager()
    print("step-4")
    s_dict = manager.dict()
    print("finish")

И setup.py (для cx_Freeze):

import cx_Freeze

executables = [cx_Freeze.Executable("main_script.py")]

cx_Freeze.setup(
    name="Example",
    options={
        "build_exe": {
            "replace_paths": [("*", "")]
        },
    },
    executables=executables
)

Проблема:

После создания исполняемого файла с помощью команды python setup.py build Я запустил его и в журнале консоли содержалось следующее:

step-1
step-2
step-3
step-1
step-2
step-3
step-1
step-2
step-3
...

И порождались бесконечные процессы.
Я понимаю, что multiprocessing.Manager() должен породить "серверный" процесс. Но не могу понять текущее поведение и то, как заставить его создать «общий диктат»

Важно:

multiprocessing.set_start_method("spawn") не может быть изменено и требуется из-за поведения основной программы.

Вопрос:

Как добиться создания manager.dict() в текущей конфигурации?

PS:

Нет проблем при запуске с обычным python <filename> (очевидно)

1 Ответ

0 голосов
/ 17 февраля 2020

Важно понимать, что делает set_start_method("spawn").

Нет смысла запускать ваш скрипт как предварительно скомпилированный исполняемый файл и ожидать, что set_start_method("spawn") будет просто работать, потому что "spawn" здесь означает " Запустите мои дочерние процессы путем повторного вызова интерпретатора », но« интерпретатор »- это ваша предварительно скомпилированная программа!

Когда вы запускаете свою программу, вы получаете бомбу-вилку, потому что многопроцессорный модуль пытается порождать следующие процессы:

$ ./main_script --multiprocessing-fork tracker_fd=6 pipe_handle=8
$ ./main_script -S -E -c 'from multiprocessing.semaphore_tracker import main;main(5)'

Это не сработает с вашей предварительно скомпилированной программой. Вам потребуется явно exec в интерпретатор python или обработать эти случаи, если вы хотите, чтобы set_start_method("spawn") работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...