信封:

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>运行,则没有问题(显而易见)

最佳答案

了解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)'

这不适用于您的预编译程序。如果您希望exec正常工作,则需要在python解释器中显式添加set_start_method("spawn")或处理这些情况。

关于python - 在 “spawn”类型进程的情况下,Ubuntu,cx_Freeze和multiprocessing.Manager()发生冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60228008/

10-12 21:24