Python 对runpy使用多处理

Python 对runpy使用多处理,python,python-multiprocessing,runpy,Python,Python Multiprocessing,Runpy,我有一个Python模块,它使用多处理。我正在使用runpy从另一个脚本执行此模块。但是,这会导致(1)模块运行两次,(2)多处理作业永远不会完成(脚本只是挂起) 在我的最小工作示例中,我有一个脚本runpy\u test.py: import runpy runpy.run_module('module_test') from multiprocessing import Pool print 'start' def f(x): return x*x pool = Pool() r

我有一个Python模块,它使用
多处理
。我正在使用
runpy
从另一个脚本执行此模块。但是,这会导致(1)模块运行两次,(2)多处理作业永远不会完成(脚本只是挂起)

在我的最小工作示例中,我有一个脚本runpy\u test.py

import runpy
runpy.run_module('module_test')
from multiprocessing import Pool

print 'start'
def f(x):
    return x*x
pool = Pool()
result = pool.map(f, [1,2,3])
print 'done'
以及一个目录模块测试,其中包含一个空的\uuuu init\uuuu.py和一个\uuuu main\uuuuu.py

import runpy
runpy.run_module('module_test')
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
调用(或者直接运行\uuuu main\uuuu.py,包括
pool.map
调用),我会得到:


我正在使用Python 2.7.5在Scientific Linux 7.6上运行它。

尝试在单独的模块中定义函数
f
。它需要序列化才能传递给池进程,然后这些进程需要通过导入它所在的模块来重新创建它。但是,它所在的
\uuuuu main\uuuuuuuuuy.py
文件不是一个模块,或者至少不是一个性能良好的模块。尝试导入它将导致创建另一个池和调用另一个map,这似乎是灾难的原因。

重写您的
\uuuuuuu main\uuuuuuuuy.py
如下所示:

from multiprocessing import Pool
from .implementation import f

print 'start'
pool = Pool()
result = pool.map(f, [1,2,3])
print 'done'
然后编写一个
implementation.py
(您可以随意调用它),其中定义了您的函数:

def f(x):
    return x*x
否则,在多处理中的大多数接口都会遇到相同的问题,并且与使用runpy无关。正如@Weeble所解释的,当
Pool.map
尝试在每个子进程中加载函数
f
时,它将导入定义函数的
。\uuuuuuu main\uuuuuu
,但由于在
\uuuu main\uuuuuu
中有模块级的可执行代码,因此子进程将重新执行该函数


除了这个技术原因之外,在关注点和测试分离方面,这也是更好的设计。现在,您可以轻松地导入和调用(包括出于测试目的)函数
f
,而无需并行运行它。

虽然不是“正确”的方法,但对我来说,一个解决方案是使用runpy的
\u run\u module\u作为主
而不是
run\u module
。这对我来说非常理想,因为我使用的是其他人的代码,并且需要最少的更改。

您的
模块测试在不删除
池的情况下运行良好。map
对我来说。@SreejithMenon澄清一下,您是否通过
runpy
调用模块?不,我直接调用模块。我不知道通过runpy调用它是否是问题所在。@SreejithMenon抱歉,我应该更清楚一些。直接调用模块对我也很有用。只有当我尝试通过
runpy
时,我才会遇到这个问题。