2

我有两个独立的函数。他们每个人都需要相当长的时间来执行。两个函数并行使用多个参数和返回值

def function1(arg): 
    do_some_stuff_here 
    return result1 

def function2(arg1, arg2, arg3): 
    do_some_stuff_here 
    return result2 

我想并行启动它们,得到它们的结果(知道哪个是哪个),然后处理结果。对于我所理解的,多处理比Python 2.7中的线程更有效率(GIL相关问题)。但是我有点遗憾,不管是使用Process,Pool还是Queue,以及如何以正确的pythonic方式来实现它们,我的用例都会更好。

任何帮助理解;)

+1

吉尔与CPU绑定操作干扰,但并没有真正影响到IO绑定操作。你的功能在做什么类型的东西? – Blender

+0

这些函数执行相同的通用类型的东西:通过http请求获取数据,将它们存储在内存中,执行一些处理并将它们转换为numpy数组。 – PsychicLocust

+0

“一般”不是很具体。试试线程和多处理,看看是否有区别,使用这两个模块的API是相似的。 – Blender

回答

4

首先,过程,游泳池和队列都具有不同的使用情况。

过程用于通过创建Process对象来产生一个过程。

from multiprocessing import Process 

def method1(): 
    print "in method1" 
    print "in method1" 

def method2(): 
    print "in method2" 
    print "in method2" 

p1 = Process(target=method1) # create a process object p1 
p1.start()     # starts the process p1 
p2 = Process(target=method2) 
p2.start() 

池用于并行跨多个 输入值的功能执行。

from multiprocessing import Pool 

def method1(x): 
    print x 
    print x**2 
    return x**2 

p = Pool(3) 
result = p.map(method1, [1,4,9]) 
print result   # prints [1, 16, 81] 

队列被用于进程间通信。现在

from multiprocessing import Process, Queue 

def method1(x, l1): 
    print "in method1" 
    print "in method1" 
    l1.put(x**2) 
    return x 

def method2(x, l2): 
    print "in method2" 
    print "in method2" 
    l2.put(x**3) 
    return x 

l1 = Queue() 
p1 = Process(target=method1, args=(4, l1,)) 
l2 = Queue() 
p2 = Process(target=method2, args=(2, l2,)) 
p1.start() 
p2.start()  
print l1.get()   # prints 16 
print l2.get()   # prints 8 

,为你的情况下,你可以使用过程&队列(第3方法),或者你可以操纵池方法的工作(见下文)

import itertools 
from multiprocessing import Pool 
import sys 

def method1(x):   
    print x 
    print x**2 
    return x**2 

def method2(x):   
    print x 
    print x**3 
    return x**3 

def unzip_func(a, b): 
    return a, b  

def distributor(option_args): 
    option, args = unzip_func(*option_args) # unzip option and args 

    attr_name = "method" + str(option)    
    # creating attr_name depending on option argument 

    value = getattr(sys.modules[__name__], attr_name)(args) 
    # call the function with name 'attr_name' with argument args 

    return value 


option_list = [1,2]  # for selecting the method number 
args_list = [4,2]   
# list of arg for the corresponding method, (argument 4 is for method1) 

p = Pool(3)    # creating pool of 3 processes 

result = p.map(distributor, itertools.izip(option_list, args_list)) 
# calling the distributor function with args zipped as (option1, arg1), (option2, arg2) by itertools package 
print result    # prints [16,8] 

希望这有助于。

0

这是我刚刚发现了另一个例子,希望有帮助,好和容易;)

from multiprocessing import Pool 

def square(x): 
    return x * x 

def cube(y): 
    return y * y * y 

pool = Pool(processes=20) 

result_squares = pool.map_async(square, range(10)) 
result_cubes = pool.map_async(cube, range(10)) 

print result_squares.get(timeout=3) 
print result_cubes.get(timeout=3)