我正在尝试将一个使用多处理的简单模块导入到我的主文件中。使用多处理的模块从 asyncresult.get()
获取计算结果。当通过导入脚本调用此例程时,脚本会挂起而不会继续。
这是一个小例子。
import_test.py(要导入的模块)
import sys
import multiprocessing as mp
if not hasattr(sys.stdin, 'close'):
def dummy_close():
pass
sys.stdin.close = dummy_close
# simple test function to compute in parallel
def testf(x):
return x*x
# multiprocessing code
pool = mp.Pool()
results = []
for i in range(0,2):
results.append(pool.apply_async(testf, [i]))
for i in range(0,2):
print results[i].get()
pool.close()
pool.join()
main.py(只导入代码并应从 import_test 打印内容的简单脚本)
if __name__ == '__main__':
import import_test
print "done"
运行脚本时我可以看到导入发生了,但是第一次 results[i].get()
(asyncresult.get()
例程)被称为整个脚本挂起并且不会在不抛出任何错误的情况下继续。我已经在运行两个明显不同的 python 设置的 Mac OS X (El Capitan) 和 Windows 10 下对此进行了测试。结果始终是上述行为。
如果我将导入模块中的代码放入 main.py
本身,一切正常。当然我的实际代码比这更复杂,我想在要导入的模块中保留并行计算。
我该如何解决这个问题?
最佳答案
我可能来得太晚了,但我想我已经找到了你问题的答案。我前一段时间也有同样的情况。它源于 Python 在导入过程中如何处理 GIL 锁,以及它如何与多进程发生冲突而造成死锁。
你应该看看https://docs.python.org/2/library/imp.html .问题如下:Python 在执行导入时获取 GIL 锁并在最后释放它。因此,当您在导入的模块中通过多处理运行线程并且它需要获取锁时,就会发生死锁。这就是为什么我建议您在主文件中进行多处理。
如果出于某种原因你绝对想在导入过程中进行多处理,还有一个解决方案:
import imp
if imp.lock_held():
imp.release_lock()
# do your multiprocessing stuff
imp.acquire_lock() # Don't forget this import needs to have the lock acquired at the end of the import
如果您不让 imp 重新获取锁,您将得到一个运行时异常。
我希望这对某人有所帮助。
关于python脚本卡在带有多处理代码的导入模块上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35090521/