Python多处理 - 如何创建并行化for循环的函数

时间:2016-09-20 10:51:08

标签: python-3.x multiprocessing jupyter-notebook python-multiprocessing

如果你打开一个Jupyter笔记本并运行它:

import multiprocessing
def f(x):
    a = 3 * x
    pool = multiprocessing.Pool(processes=1)
    global g
    def g(j):
        return a * j
    return pool.map(g, range(5))
f(1)

您将收到以下错误

Process ForkPoolWorker-1:
Traceback (most recent call last):
  File "/Users/me/anaconda3/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
    self.run()
  File "/Users/me/anaconda3/lib/python3.5/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/me/anaconda3/lib/python3.5/multiprocessing/pool.py", line 108, in worker
    task = get()
  File "/Users/me/anaconda3/lib/python3.5/multiprocessing/queues.py", line 345, in get
    return ForkingPickler.loads(res)
AttributeError: Can't get attribute 'g' on <module '__main__'>

我试图了解这是一个错误还是一个功能。

我试图让它工作,因为在我的实际情况中f基本上是一个易于并行化的for循环(每次迭代只更改一个参数),但每次迭代需要花费大量时间!我是否正确处理问题或者是否有更简单的方法? (注意:整个笔记本中f将被调用几次,不同的参数本身)

2 个答案:

答案 0 :(得分:2)

如果您在g之外定义f,则可以正常工作。

import multiprocessing

def g(j):
    return 4 * j

def f():
    pool = multiprocessing.Pool(processes=1)
    return pool.map(g, range(5))

f()

修改: 在示例中,您输入的问题可调用对象看起来有点像这样:

class Calculator():
    def __init__(self, j):
        self.j = j

    def __call__(self, x):
        return self.j*x

你的函数f就像这样:

def f(j):
    calculator = Calculator(j) 
    pool = multiprocessing.Pool(processes=1)
    return pool.map(calculator, range(5))

我在这种情况下工作得很好。希望它有所帮助。

答案 1 :(得分:1)

如果要将g应用于更多参数而不仅仅是pool.map传递的迭代器元素,则可以使用functools.partial,如下所示:

import multiprocessing
import functools

def g(a, j):
    return a * j

def f(x):
    a = 3 * x
    pool = multiprocessing.Pool(processes=1)
    g_with_a = functools.partial(g, a)
    return pool.map(g_with_a, range(5))

f(1)

functools.partial的作用是获取函数和任意数量的参数(通过位置和关键字)并返回一个新函数,其行为类似于传递给它的函数,但只接受参数没有传递给partial

partial返回的函数可以顺利腌制i。即传递给pool.map,只要你使用的是python3。

这与Darth Kotik在答案中描述的基本相同,但你不必自己实施Calculator课程,因为partial已经做了你想做的事。