【问题标题】:Python multiprocessing pool function not definedPython多处理池函数未定义
【发布时间】:2023-04-04 19:12:01
【问题描述】:

我需要实现一个使用任意包进行计算的多处理池。为此,我使用 Python 和 joblib 0.9.0。这段代码基本上就是我想要的结构。

import numpy as np
from joblib import pool

def someComputation(x):
    return np.interp(x, [-1, 1], [-1, 1])

if __name__ == '__main__':
    some_set_of_numbers = [-1,-0.5,0,0.5,1]
    the_pool = pool.Pool(processes=2)
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers]
    print(solutions[0].get())

在运行 Anaconda 4.3.1 Python 3.6.0(以及带有虚拟环境的 3.5 和 3.4)的 Windows 10 和 Red Hat Enterprise Linux 上,我知道 'np' 从未传递到 someComputation() 函数中,从而提高了错误

File "C:\Anaconda3\lib\site-packages\multiprocessing_on_dill\pool.py", line 608, in get
    raise self._value
NameError: name 'np' is not defined

但是,在我运行 Python 3.5 和相同 joblib 的 Mac OS X 10.11.6 上,我使用完全相同的代码获得了“-1”的预期输出。 This 问题本质上是相同的,但它处理的是悲情而不是 joblib。一般的答案是在函数中包含 numpy import 语句

from joblib import pool

def someComputation(x):
    import numpy as np
    return np.interp(x, [-1, 1], [-1, 1])

if __name__ == '__main__':
    some_set_of_numbers = [-1,-0.5,0,0.5,1]
    the_pool = pool.Pool(processes=2)
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers]
    print(solutions[0].get())

这解决了 Windows 和 Linux 机器上的问题,它们现在按预期输出“-1”,但这个解决方案看起来很笨拙。有什么理由为什么第一段代码可以在 Mac 上运行,而不是在 Windows 或 Linux 上运行?我最终需要在 Linux 机器上运行这段代码,那么是否有任何修复不包括将 import 语句放入函数中?

编辑:

在进一步调查后,我发现我多年前提出的一个旧解决方法似乎是导致问题的原因。在 joblib/pool.py 中,我将第 44 行从

from multiprocessing.pool import Pool

from multiprocessing_on_dill.pool import Pool

支持任意函数的酸洗。出于某种原因,这种变化才是真正导致 Windows 和 Linux 出现问题的原因,但 Mac 机器运行良好。使用 multiprocessing 而不是 multiprocessing_on_dill 可以解决上述问题,但该代码不适用于我的大多数情况,因为它们不能被腌制。

【问题讨论】:

  • 不确定这是否能回答您的问题,但比将导入导入函数更好的方法是将其声明为def someComputation(x, np=np):。这应该在第一次解释模块时将模块绑定到函数内的本地名称,从而避免每次都运行导入机制。
  • 效果很好,我当然可以使用它,直到我们找出真正的问题。

标签:
python
linux
function
multiprocessing
joblib