Python 脚本挂起在导入具有多处理代码的模块上



我正在尝试导入一个简单的模块,该模块使用多处理到我的主文件中。使用多处理的模块从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 重新获取锁,你将得到一个运行时异常。

我希望这对某人有所帮助。

有趣的是,当你把它放在 main.py 中时,你的代码可以工作。你能尝试将代码移动到函数中吗?按照您现在的方式,导入完成后,代码就会被执行。这至少可以让您控制何时运行代码。

import_test.py:

import sys
import multiprocessing as mp
def run():
    <your code>

main.py:

if __name__ == '__main__':
    import import_test
    import_test.run()

相关内容

  • 没有找到相关文章

最新更新