繁体   English   中英

在 runpy 中使用多处理

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM