Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理池卡住了_Python_Threadpool_Ipython Notebook_Python Multiprocessing - Fatal编程技术网

Python多处理池卡住了

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

我正在尝试运行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)
但是当我尝试运行它时,它永远无法完成执行,我必须重新启动IpythonNotebook的内核。 问题出在哪里?

正如John在评论中指出的那样,
多处理.Pool
通常不应在交互式解释器中正常工作。要理解为什么会出现这种情况,请考虑<代码>池< <代码>的工作:

  • 它分叉python工作人员,将当前python文件的名称传递给他们
  • 然后,工人基本上执行
    导入
    ,并侦听来自主机的消息
  • 主节点通过pickle将函数名和函数参数一起发送给工作节点。请注意,函数本身无法发送,因为pickle协议不允许这样做
当您尝试从交互式提示执行此过程时,没有合理的“当前Python文件”可传递给子级进行导入。此外,在交互式提示中定义的函数不是任何模块的一部分(它们是动态定义的),因此子模块无法从不存在的模块导入。因此,最简单的方法就是避免在IPython中使用
多处理。不管怎么说,情况好多了:)


为了完整起见,我还检查了在Windows8上运行Python2.7下的iPython4的具体情况(我可以看到解释器也卡住了)。有趣的是,IPython首先陷入困境的原因并不是上面提到的原因之一

结果是,多处理检查是否定义了
\uuuuuuu main\uuuuu.\uuuuu file\uuuuuuu
,如果未定义,则将
sys.argv[0]
作为“当前文件名”发送给子级。在(我的版本)的情况下,IPython
sys.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
、操作系统等的版本。这是否回答了您的问题?