Python多处理池卡住了
我正在尝试运行python的multiprocessing.pool模块的一些示例代码,该模块可以在web上找到。代码是:Python多处理池卡住了,python,threadpool,ipython-notebook,python-multiprocessing,Python,Threadpool,Ipython Notebook,Python Multiprocessing,我正在尝试运行python的multiprocessing.pool模块的一些示例代码,该模块可以在web上找到。代码是: def square(x): return x * x if __name__ == '__main__': pool = Pool(processes=4) inputs = [0, 1, 2, 3, 4] outputs = pool.map(square, inputs) 但是当我尝试运行它时,它永远无法完成执行,我必须重新启动Ipy
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的内核。
问题出在哪里?正如John在评论中指出的那样,多处理.Pool
通常不应在交互式解释器中正常工作。要理解为什么会出现这种情况,请考虑<代码>池< <代码>的工作:
- 它分叉python工作人员,将当前python文件的名称传递给他们
- 然后,工人基本上执行
,并侦听来自主机的消息导入
- 主节点通过pickle将函数名和函数参数一起发送给工作节点。请注意,函数本身无法发送,因为pickle协议不允许这样做
多处理。不管怎么说,情况好多了:)
为了完整起见,我还检查了在Windows8上运行Python2.7下的iPython4的具体情况(我可以看到解释器也卡住了)。有趣的是,IPython首先陷入困境的原因并不是上面提到的原因之一
结果是,多处理检查是否定义了\uuuuuuu main\uuuuu.\uuuuu file\uuuuuuu
,如果未定义,则将sys.argv[0]
作为“当前文件名”发送给子级。在(我的版本)的情况下,IPythonsys.argv[0]
等于C:\Dev\Anaconda\lib\site packages\ipykernel\\uuuuuuuuu main.py
不幸的是,工作进程在启动前会检查要导入的文件是否已经在其sys.modules
中。multiprocessing/forking.py
的第488行说:
assert main_name not in sys.modules, main_name
当main\u name
为\uuuu main\uuuu
时(与ipython的工作程序一样),此断言失败,工作程序无法启动。但是,相同的代码足够“智能”来检查传递的名称是否为ipython
,在这种情况下,它不会进行此类检查,也不会导入任何内容
因此,工人无法启动的问题可以通过定义\uuuuuu main\uuuuu.\uuuu file\uuuuuu
等于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
。如果您要求工作人员计算您在笔记本中定义的函数,则会失败(正常情况下,有例外)
事实证明,原则上,您可以进一步进行黑客攻击,并将您的功能发送给工人,使用一些手动酸洗他们的代码。您可以找到这样一个非常酷的黑客示例。该代码在常规(非笔记本)Python中工作。你能确认它在笔记本之外的系统上工作吗?您是否也可以使用常规的
map()
替换池部分,以确认其在笔记本中正常工作?See也适用于我。您可能需要添加更多详细信息,例如ipython
、操作系统等的版本。这是否回答了您的问题?