2

私は2つの別々の関数を持っています。それぞれには実行にかなりの時間がかかります。複数の引数と戻り値と並列の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関連の問題)よりも効率的です。しかし、プロセス、プール、またはキューを使用する方が良いかどうか、そして私のユースケースのために正しいpythonicな方法でそれらを実装する方が良いかどうか、少し失われています。すべてのヘルプは感謝

;)すべての

+1

GILはCPUバウンドの操作を妨げるが、本当にIOバウンドの操作には影響しません。あなたの機能はどのようなものですか? – Blender

+0

関数は同じ一般的な種類の処理を行います。httpリクエストを介してデータを取得し、メモリに格納し、何らかの処理を行いnumpy配列に変換します。 – PsychicLocust

+0

「一般」はあまり具体的ではありません。スレッディングとマルチプロセッシングの両方を試して、違いがあるかどうかを確認するには、両方のモジュールを使用するためのAPIが似ています。 – Blender

答えて

4

まず、プロセス、プールおよびキューのすべてが異なるユースケースを持っています。

プロセスは、プロセスオブジェクトを作成することによってプロセスを生成するために使用されます。

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) 
関連する問題