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

时间:2016-01-29 17:30:29

标签: python multiprocessing python-multiprocessing

我正在尝试导入一个简单的模块,它在我的主文件中使用多处理。使用多处理的模块从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()例程)时整个脚本挂起并且不会继续而不会抛出任何错误。我在Mac OS X(El Capitan)和Windows 10下运行了两个明显不同的python设置。结果始终是上述行为。

如果我只是将导入模块中的代码放入main.py本身,那么一切正常。当然我的实际代码比这更复杂,我想在要导入的模块中保持并行计算。

如何解决此问题?

2 个答案:

答案 0 :(得分:5)

我可能来得太晚了,但我想我能回答你的问题。我有一段时间回来了。它源于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重新获得锁定,那么你将获得运行时异常。

我希望这显示对某人有帮助。

答案 1 :(得分:1)

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

import_test.py:

<h1>Welcome to the Random Color Game.</h1>
<div id="myNumberOfRounds">
  How many many rounds of the game would you like?
  <p>
    I would like
    <input id="setNumberOfRounds" type="number" min="1" max="20" name="numberOfRounds"> 
    rounds.
  </p>
  To start playing the game, push begin.
  <p>
    <button onclick="getNumberOfRounds()">Begin</button>
  </p>
</div>

在main.py中:

import sys
import multiprocessing as mp

def run():
    <your code>