给出 AttributeError 的多处理实例

我试图在我的代码中实现多处理,因此,我认为我应该从一些示例开始我的学习。我使用了在这个 documentation中找到的第一个例子。

from multiprocessing import Pool
def f(x):
return x*x


if __name__ == '__main__':
with Pool(5) as p:
print(p.map(f, [1, 2, 3]))

当我运行以上代码时,我得到一个 AttributeError: can't get attribute 'f' on <module '__main__' (built-in)>。我不知道为什么我得到这个错误。如果有帮助的话,我还会使用 Python 3.5。

85533 次浏览

这个问题似乎是多处理的一个设计特点。泳池。参见 https://bugs.python.org/issue25053。由于某些原因,Pool 并不总是使用未在导入模块中定义的对象。因此,您必须将函数写入另一个文件并导入模块。

File: defs.py

def f(x):
return x*x

档案: 跑吧 Py

from multiprocessing import Pool
import defs


if __name__ == '__main__':
with Pool(5) as p:
print(p.map(defs.f, [1, 2, 3]))

If you use print or a different built-in function, the example should work. If this is not a bug (according to the link), the given example is chosen badly.

如果您使用 Jupiter 笔记本(比如 OP) ,那么在单独的单元格中定义函数并执行该单元格首先解决问题。接受的答案也有用,但需要做更多的工作。在池之前(即池之上)定义函数是不够的。它必须在一个完全不同的笔记本电脑单元,首先执行。

在使用 IPython 时,multiprocessing模块有一个主要限制:

此包中的功能要求 __main__模块为 这意味着一些例子,例如 因为 multiprocessing.pool.Pool示例在 交互式解释器

幸运的是,multiprocessing模块中有一个分支叫做 multiprocess,它使用 dill而不是 pickle来序列化,并且很方便地克服了这个问题。

只需在导入中安装 multiprocess并用 multiprocess替换 multiprocessing:

import multiprocess as mp


def f(x):
return x*x


with mp.Pool(5) as pool:
print(pool.map(f, [1, 2, 3, 4, 5]))

当然,按照 这个答案中的建议将代码外部化也可以工作,但是我发现它非常不方便: 这不是我使用 IPython 环境的原因(以及如何使用)。

multiprocessing不能立即在 IPython 环境中工作,而是使用它的 fork multiprocess

这个答案是给那些在 二零二一年视窗10上得到这个错误的人的。

I've researched this error a bit since I got it myself. I get this error when running any examples from the official Python 3 documentation on multiprocessing.

测试环境:

  • X86 Windows 10.0.19043.1165 + Python 3.9.2-有一个错误
  • X86 Windows 10.0.19043.1165 + Python 3.9.6-有一个错误
  • x86 Windows 10.0.19043.1110 + Python 3.9.6 - there is an error
  • ARM Windows 10.0.21354.1 + Python 3.9.6-无错误(来自 DEV 分支的版本)
  • ARM macOS 11.5.2 + Python 3.9.6-无错误

我没有办法在其他条件下测试这种情况。但是我猜测问题出在 Windows 上,因为在开发者版本“10.0.21354.1”中没有这样的 bug,但是这个 ARM 版本可能有 x86仿真。

还要注意的是,在 Python 3.9.2发布的时候(2月)并没有这样的 bug。因为一直以来我都在同一台计算机上工作,当以前工作的代码停止工作,只有 Windows 版本发生变化时,我感到很惊讶。

我无法在 Python bug 跟踪器中找到具有类似情况的 bug 请求(我可能搜索得不好)。标有“正确答案”的信息指的是另一种情况。这个问题很容易重现,您可以尝试遵循新安装的 Windows10 + Python3上的多处理文档中的任何示例。

稍后,我将有机会查看 Python 3.10和最新版本的 Windows 10。 I am also interested in this situation in the context of Windows 11.

如果您有关于这个错误的信息(链接到 bug 跟踪器或类似的东西) ,一定要分享它。

At the moment I switched to Linux to continue working.

为什么不使用 joblib? 你的代码相当于:

# pip install joblib


from joblib import Parallel, delayed




def f(x):
return x*x


res = Parallel(
n_jobs=5
)(
delayed(f)(x) for x in [1, 2, 3]
)