Python 未定义多处理池函数

Python multiprocessing pool function not defined

我需要实现一个使用任意包进行计算的多处理池。为此,我使用 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())

在 Windows 10 和 Red Hat Enterprise Linux 运行ning Anaconda 4.3.1 Python 3.6.0(以及带有虚拟环境的 3.5 和 3.4)上), 我知道 '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

然而,在我的 Mac OS X 10.11.6 运行ning Python 3.5 和相同的 joblib 上,我得到了预期的输出 '-1'使用完全相同的代码。 This 问题本质上是相同的,但它处理的是 pathos 而不是 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 解决了上述问题,但代码不适用于我的大多数情况,因为它们无法被腌制。

我不确定确切的问题是什么,但似乎将全局范围转移到 运行 任务的子进程时出现了一些问题。您可以通过将名称 np 绑定为函数参数来避免名称错误:

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

这样做的好处是不需要每次函数 运行 时都调用导入机制。名称 np 将在模块加载期间首次评估时绑定到该函数。