Python多处理池卡住了

标签 python threadpool ipython-notebook python-multiprocessing

我正在尝试运行在网上找到的 python 的 multiprocessing.pool 模块的一些示例代码。代码是:

def square(x):
    return x * x
if __name__ == '__main__':
    pool = Pool(processes=4)
    inputs = [0, 1, 2, 3, 4]
    outputs = pool.map(square, inputs)

但是当我尝试运行它时,它从未完成执行,我不得不重新启动我的 IpythonNotebook 笔记本的内核。 有什么问题?

最佳答案

正如您可能从 the answer 中读到的那样约翰在评论中指出,multiprocessing.Pool ,一般来说,不应期望在交互式解释器中运行良好。要理解为什么会这样,请考虑如何 Pool做它的工作:

  • 它 fork python worker,将当前 Python 文件的名称传递给他们。
  • 然后 worker 基本上做import <this file> , 并听取 master 的消息。
  • master 通过 pickling 将函数名称连同函数参数发送给 worker。请注意,不能发送函数本身,因为 pickle 协议(protocol)不允许这样做。

当您尝试从交互式提示执行此过程时,没有合理的“当前 Python 文件”传递给子项以供导入。此外,您在交互式提示中定义的函数不是任何模块的一部分(它们是动态定义的),因此子项不能从该不存在的模块中导入。所以你最简单的选择就是避免使用 multiprocessing在 IPython 中。 IPython parallel反正好多了:)


为了完整起见,我还检查了在 Windows 8 上运行在 Python 2.7 下的 IPython 4 的特定情况下到底发生了什么(我也可以观察到解释器卡住了)。有趣的是,IPython 卡在第一位的原因并不是上面提到的原因之一。

原来 multiprocessing 检查是否 __main__.__file__已定义,如果未定义,则发送 sys.argv[0]作为 children 的“当前文件名”。对于(我的版本)IPython sys.argv[0]等于C:\Dev\Anaconda\lib\site-packages\ipykernel\__main__.py .

不幸的是,工作进程在启动前恰好检查他们要导入的文件是否已经在他们的sys.modules中。 . multiprocessing/forking.py 的第 488 行说:

assert main_name not in sys.modules, main_name

main_name__main__ (就像 ipython 的 worker 一样)这个断言失败并且 worker 无法启动。然而,相同的代码足够“智能”以检查传递的名称是否为 ipython。 ,在这种情况下,它不会进行此类检查,也不会导入任何内容。

因此,worker 无法启动的问题可以通过定义 __main__.__file__ 来解决。等于ipython .以下代码在 IPython 单元中运行良好:

import sys
sys.modules['__main__'].__file__ = 'ipython'
from multiprocessing import Pool

pool = Pool(processes=4)
inputs = [0, 1, 2, 3, 4]
outputs = pool.map(abs, inputs)

请注意,此示例要求工作人员计算 abs , 内置函数。如果您要求工作人员计算您在笔记本中定义的函数,它将失败(优雅地,有一个异常(exception))。

事实证明,原则上您可以更进一步地进行黑客攻击,并通过对代码进行一些手动 pickling 将您的函数发送给工作人员。您可以找到此类 hack 的一个非常酷的示例 here .

关于Python多处理池卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34086112/

相关文章:

ipython - 将正在运行的 ipython 笔记本与进程匹配

Mac 上的 PythonXY?

python - 如何重新启动 BaseHTTPServer 实例?

python - mrjob.conf 文件的位置是什么?

python - ThreadPoolExecutor 记录? (Python)

python - 交互式 Python - 相对导入的解决方案

amazon-ec2 - 从远程服务器运行 ipython notebook

python mechanize._html.ParseError

javascript - 如何在 Javascript 中锁定线程?

java - 具有可调用的线程池