[英]cx-freeze, runpy and multiprocessing - multiple paths to failure
[英]Using multiprocessing with runpy
我有一个使用multiprocessing
的 Python 模块。 我正在使用runpy
从另一个脚本执行此模块。 但是,这会导致 (1) 模块运行两次,以及 (2) multiprocessing
作业永远不会完成(脚本只是挂起)。
在我的最小工作示例中,我有一个脚本runpy_test.py :
import runpy
runpy.run_module('module_test')
和一个目录module_test包含一个空的__init__.py和一个__main__.py :
from multiprocessing import Pool
print 'start'
def f(x):
return x*x
pool = Pool()
result = pool.map(f, [1,2,3])
print 'done'
当我运行runpy_test.py时,我得到:
start
start
脚本挂起。
如果我删除pool.map
调用(或者如果我直接运行__main__.py ,包括pool.map
调用),我会得到:
start
done
我在 Python 2.7.5 中的 Scientific Linux 7.6 上运行它。
尝试在单独的模块中定义您的 function f
。 它需要被序列化以传递给池进程,然后这些进程需要通过导入它所在的模块来重新创建它。但是,它所在的__main__.py
文件不是模块,或者至少,不是一个乖巧的人。 尝试导入它会导致创建另一个池并再次调用 map,这似乎是灾难的根源。
像这样重写你的__main__.py
:
from multiprocessing import Pool
from .implementation import f
print 'start'
pool = Pool()
result = pool.map(f, [1,2,3])
print 'done'
然后编写一个implementation.py
(你可以随意调用它),其中定义了你的 function:
def f(x):
return x*x
否则,您将在多处理中的大多数接口上遇到相同的问题,并且与使用 runpy 无关。 As @Weeble explained, when Pool.map
tries to load the function f
in each sub-process it will import <your_package>.__main__
where your function is defined, but since you have executable code at module-level in __main__
it will be re - 由子进程执行。
除了这个技术原因,这在关注点分离和测试方面也是更好的设计。 现在您可以轻松导入和调用(包括用于测试目的)function f
,而无需并行运行。
虽然不是“正确”的方法,但最终为我工作的一种解决方案是使用 runpy 的_run_module_as_main
而不是run_module
。 这对我来说非常理想,因为我正在使用其他人的代码并且需要最少的更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.