信封:
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/