简体   繁体   English

Python多处理包装器

[英]Python multiprocessing wrapper

I have a simple multiprocessing wrapper. 我有一个简单的multiprocessing包装器。 Which takes a function and runs it in parallel and get the data back. 它需要一个函数并并行运行它并取回数据。

However, I seem to be hard-coding my arguments (see apply() ) . 但是,我似乎在对参数进行硬编码(请参见apply() )。 I am not sure how I can pass a more dynamic argument list. 我不确定如何传递更动态的参数列表。

Here is my code 这是我的代码

import multiprocessing as mp                                                     
import time                                                                      

class MPWrap(object):                                                            
    def __init__(self,verbose=False):                                            
        self.a=mp.Pool(10)                                                       
        self.resultObj=[]                                                        
        self.verbose=verbose                                                     

    def apply(self,func,args):                                                   
        for i in args:                                                           
            self.resultObj.append(                                               
                    self.a.apply_async(func,kwds={'x':i})                        
                )                                                                

    def status(self):                                                            
        incomplete_count = sum(1 for x in self.resultObj if not x.ready())       
        if self.verbose:                                                         
          s="todo %d/%d tasks"%(incomplete_count,len(self.resultObj))            
          print s                                                                
        return incomplete_count                                                  

    def get(self):                                                               
        return  [ i.get() for i in self.resultObj ]                              

    def __del__(self):                                                           
        self.a.close()                                                           
        self.a.join()                                                            
        print "Done..."                                                          



def square(x):                                                                   
    time.sleep(x)                                                                
    return x*x                                                                   

def main():                                                                      
    x=MPWrap()                                                                   

    x.apply(square,                                                              
            args=[1,2,3,4,5,6,7,8,9]                                             
            )                                                                    
    while x.status() is None:                                                    
        time.sleep(.5)                                                           
        if x.status()==0:break                                                   
    print x.get()  

if __name__=="__main__":                                                                      x[1, 4, 9, 16, 25, 36, 49, 64, 81]
    main()         

Using functions to generate function arguments should work: 使用函数生成函数参数应该可以:

def apply(self,func,args,fargs=lambda i:(),fkwargs=lambda i:{}):                                                   
    for i in args:                                                           
        self.resultObj.append(                                               
                self.a.apply_async(func,fargs(i),fkwargs(i))                        
            )

and

x.apply(square,                                                              
        args=[1,2,3,4,5,6,7,8,9],
        fkwargs=lambda i: {'x':i}                                             
        ) 

apply_async is to run independent single tasks. apply_async用于运行独立的单个任务。 If you have a group of identical tasks you should be using map_async or one of its variants. 如果您有一组相同的任务,则应使用map_async或其变体之一。 I'm not actually sure what your wrapper is providing that doesn't already come from map_async . 我实际上不确定您提供的包装器是否已经来自map_async

Consider: 考虑:

def main():
    x = Pool(10)
    res = x.map_async(square, range(1,10))
    while not res.ready():
        res.wait(0.5)
    print res.get()

ETA: If you want to generalise the arguments through the map function I can see some value in creating a wrapper for that purpose. ETA:如果您想通过map函数来概括参数,那么我可以看到为此目的创建包装的一些价值。 Consider maybe: 考虑一下:

def unwrap(fdesc):
    (f, args, kwargs) = fdesc
    return (f, f(*args, **kwargs))

You can then call x.map_async(unwrap, [(square, [i], {}) for i in range(1,10)]) and the results returned are in a tuple keyed with the function (so you can differentiate and interpret the results if you are using multiple functions). 然后,您可以调用x.map_async(unwrap, [(square, [i], {}) for i in range(1,10)]) ,返回的结果将存储在以该函数为键的元组中(因此您可以区分和如果您使用多个功能,请解释结果)。

Essentially with this you would create a list of tuples containing the function, the positional arguments, and the key-word arguments, and then you feed in that whole list to the one call to map_async . 本质上,您将创建一个包含函数,位置参数和关键字参数的元组列表,然后将整个列表提供给对map_async的一次调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM