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)