多进程处理带多个输入的函数

27 投票
5 回答
34970 浏览
提问于 2025-04-16 08:38

在Python中,可以使用multiprocessing模块来同时运行一个函数,处理一系列的数值。比如说,这样可以得到函数f的前100000次计算结果的列表。

def f(i):
    return i * i

def main():
    import multiprocessing
    pool = multiprocessing.Pool(2)
    ans = pool.map(f, range(100000))

    return ans

那么,如果函数f需要多个输入,但只有一个变量在变化,能否做类似的操作呢?比如说,如何让这个过程并行运行:

def f(i, n):
    return i * i + 2*n

def main():
    ans = []
    for i in range(100000):
        ans.append(f(i, 20))

    return ans

5 个回答

8

如果你使用我修改过的 multiprocessing 库,叫做 pathos,你可以创建可以接受多个参数的工作池……而且还可以使用 lambda 函数。它的好处在于,你不需要改变你的编程方式就能实现并行处理。

>>> def f(i, n):
...   return i * i + 2*n
... 
>>> from itertools import repeat
>>> N = 10000
>>>
>>> from pathos.pools import ProcessPool as Pool
>>> pool = Pool()
>>>
>>> ans = pool.map(f, xrange(1000), repeat(20))
>>> ans[:10]
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121]
>>>
>>> # this also works
>>> ans = pool.map(lambda x: f(x, 20), xrange(1000))
>>> ans[:10]
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121]
46

你可以使用 functools.partial() 这个功能。

def f(i, n):
    return i * i + 2*n

def main():
    import multiprocessing
    pool = multiprocessing.Pool(2)
    ans = pool.map(functools.partial(f, n=20), range(100000))

    return ans
15

有几种方法可以做到这一点。在问题中给出的例子里,你可以简单地定义一个包装函数

def g(i):
    return f(i, 20)

然后把这个包装函数传给 map()。还有一种更通用的方法是,定义一个包装函数,它接受一个元组作为参数,然后把这个元组拆开,变成多个参数

def g(tup):
    return f(*tup)

或者使用一个等效的 lambda 表达式:lambda tup: f(*tup)

撰写回答