在Python 3.2 [重复]并行地执行一个for循环(Perform a for-loop in

2019-07-30 14:03发布

可能重复:
我怎么并行一个简单的Python循环?

我是很新的的Python(使用Python 3.2)和我有一个关于并行化的问题。 我有一个for循环,我想在Python 3.2使用“多”并行执行:

def computation:    
    global output

    for x in range(i,j):
        localResult = ... #perform some computation as a function of i and j
        output.append(localResult)

总体而言,我想为一个范围的i = 0到J = 100执行此计算。 因此,我想创建一个数的每个调用函数“计算”与总范围的一个子进程。 如何任何想法做呢? 难道还有比使用多更好的办法?

更具体的,我想执行一个域分解和我有以下代码:

from multiprocessing import Pool

class testModule:

    def __init__(self):
        self

    def computation(self, args):
        start, end = args
        print('start: ', start, ' end: ', end)

testMod = testModule()
length = 100
np=4
p = Pool(processes=np)
p.map(yes tMod.computation, [(length, startPosition, length//np) for startPosition in    range(0, length, length//np)]) 

我得到一个错误信息提PicklingError。 任何想法可能是这里的问题?

Answer 1:

JOBLIB是专门设计成环绕多处理用于简单的并行循环的目的。 我建议使用,而不是直接多处理拼杀。

简单的情况下,看起来是这样的:

from joblib import Parallel, delayed
Parallel(n_jobs=2)(delayed(foo)(i**2) for i in range(10))  # n_jobs = number of processes

一旦你了解它的语法很简单。 我们正在使用中产生的语法delayed用于调用函数foo包含在后面的括号它的参数。

在你的情况,您应该重写你与发电机语法循环,或定义另一个功能(即“工人”功能)执行单个循环迭代的操作和地点为呼叫到并行的生成语法。

在后一种情况下,你会做这样的事情:

Parallel(n_jobs=2)(delayed(foo)(parameters) for x in range(i,j))

其中foo是一个函数定义来处理你的身体循环。 请注意,您不想追加到一个列表,因为水货反正返回一个列表。



Answer 2:

在这种情况下,你可能要定义一个简单的函数来进行计算,并得到localResult

def getLocalResult(args):
    """ Do whatever you want in this func.  
        The point is that it takes x,i,j and 
        returns localResult
    """
    x,i,j = args  #unpack args
    return doSomething(x,i,j)

现在,在您的计算功能,你只是制造工人的游泳池和映射本地结果:

import multiprocessing
def computation(np=4):
    """ np is number of processes to fork """
    p = multiprocessing.Pool(np)
    output = p.map(getLocalResults, [(x,i,j) for x in range(i,j)] )
    return output

我已经删除了全球在这里,因为这是不必要的(全局通常是不必要的)。 在您的调用程序,你应该只是做output.extend(computation(np=4))或类似的东西。

编辑

这是你的代码的“工作”的例子:

from multiprocessing import Pool

def computation(args):
    length, startPosition, npoints = args
    print(args)

length = 100
np=4
p = Pool(processes=np)
p.map(computation, [(startPosition,startPosition+length//np, length//np) for startPosition in  range(0, length, length//np)])

请注意,你有没有因为你正在使用的实例方法为您的工作功能。 多启动新进程,并发送经由进程之间的信息pickle ,因此,仅可使用可被酸洗的对象。 需要注意的是它确实没有任何意义使用实例方法。 每个进程是父进程的一个副本,因此对状态,这发生在任何过程的变化不会传播回父反正。



文章来源: Perform a for-loop in parallel in Python 3.2 [duplicate]