python脚本卡在带有多处理代码的导入模块上

标签 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()

ma​​in.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/

相关文章:

Python - 如何杀死一个进程(不是子进程)

python - 结合 itertools 和多处理?

python - Selenium Threads : How to open the same browser in multiple threads? 为每个浏览器使用唯一的代理

Python 多处理 - 进程终止(不能启动进程两次)

Python多处理: print() inside apply_async()

python - 循环遍历数据框列来进行简单的线性回归?

python - 如何在同一个主键下创建多个 DynamoDB 条目?

python - python aiohttp socketio 中是否可能存在竞争条件?

python - pandas read_sql 在列名中删除点

python - 多重处理不适用于计算矩阵叉积的函数