未定义 Python 多处理池函数

Mic*_*any 5 python linux function multiprocessing joblib

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

在运行 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
Run Code Online (Sandbox Code Playgroud)

但是,在运行 Python 3.5 和相同 joblib 的 Mac OS X 10.11.6 上,我使用完全相同的代码获得了“-1”的预期输出。这个问题本质上是一样的,但它处理的是悲情而不是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())
Run Code Online (Sandbox Code Playgroud)

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

编辑:

在进一步调查之后,我发现了我几年前提出的一个旧的解决方法,它看起来像是导致了这个问题。在 joblib/pool.py 中,我将第 44 行从

from multiprocessing.pool import Pool
Run Code Online (Sandbox Code Playgroud)

from multiprocessing_on_dill.pool import Pool
Run Code Online (Sandbox Code Playgroud)

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

Mad*_*ist 3

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

def someComputation(x, np=np):
    return np.interp(x, [-1, 1], [-1, 1])
Run Code Online (Sandbox Code Playgroud)

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