Ubuntu、cx_Freeze 和 multiprocessing.Manager() 冲突,以防“spawn”类型进程

Yur*_*nov 7 python linux ubuntu multiprocessing cx-freeze

环境:

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")
Run Code Online (Sandbox Code Playgroud)

和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
)
Run Code Online (Sandbox Code Playgroud)

问题:

通过命令构建可执行文件后,python setup.py build我运行了它,控制台日志包含以下内容:

step-1
step-2
step-3
step-1
step-2
step-3
step-1
step-2
step-3
...
Run Code Online (Sandbox Code Playgroud)

并且产生无限的过程。
我知道multiprocessing.Manager()应该产生“服务器”进程。但无法获得当前行为的线索以及如何强制它创建“共享字典”

重要的:

multiprocessing.set_start_method("spawn") 由于主程序行为,无法更改和要求。

题:

如何manager.dict()在当前配置中实现创建?

PS:

如果使用常规python <filename>(明显)运行没有问题

Mic*_*zyk 0

了解它的set_start_method("spawn")作用很重要。

将脚本作为预编译的可执行文件运行并期望set_start_method("spawn")正常工作是没有意义的,因为"spawn"这里的意思是“通过重新调用解释器来启动我的子进程”,但“解释器”是您的预编译程序!

当您运行程序时,您会收到一个 fork 炸弹,因为多处理模块尝试生成以下进程:

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

这不适用于您的预编译程序。如果你想工作,你将需要显式地exec进入 python 解释器或处理这些情况。set_start_method("spawn")