2012-04-07 5 views
2

Dieser Code zeigt die Struktur von dem, was ich versuche zu tun.Erstellen Sie eine Kopie eines Objekts, anstatt die Reinitialisierung innerhalb eines neuen Multiprocessing-Prozesses

import multiprocessing 
from foo import really_expensive_to_compute_object 

## Create a really complicated object that is *hard* to initialise. 
T = really_expensive_to_compute_object(10) 

def f(x): 
    return T.cheap_calculation(x) 

P = multiprocessing.Pool(processes=64) 
results = P.map(f, range(1000000)) 

print results 

Das Problem ist, dass jeder Prozess beginnt mit viel Zeit neu berechnet T verbringen, anstatt die ursprüngliche T zu verwenden, die einmal berechnet wurde. Gibt es einen Weg dies zu verhindern? T hat eine schnelle (tiefe) Kopiermethode, also kann ich Python dazu bringen, diese zu verwenden, anstatt sie neu zu berechnen?

Antwort

1

Warum nicht f einen T Parameter anstelle des Verweises auf die globale nehmen, und die Kopien selbst tun?

import multiprocessing, copy 
from foo import really_expensive_to_compute_object 

## Create a really complicated object that is *hard* to initialise. 
T = really_expensive_to_compute_object(10) 

def f(t, x): 
    return t.cheap_calculation(x) 

P = multiprocessing.Pool(processes=64) 
results = P.map(f, (copy.deepcopy(T) for _ in range(1000000)), range(1000000)) 

print results 
2

multiprocessing Dokumentation suggests

Explizit Ressourcen Kind-Pass-Prozesse

So können Sie Ihren Code so etwas wie dieses rewritenn werden:

import multiprocessing 
import time 
import functools 

class really_expensive_to_compute_object(object): 
    def __init__(self, arg): 
     print 'expensive creation' 
     time.sleep(3) 

    def cheap_calculation(self, x): 
     return x * 2 

def f(T, x): 
    return T.cheap_calculation(x) 

if __name__ == '__main__': 
    ## Create a really complicated object that is *hard* to initialise. 
    T = really_expensive_to_compute_object(10) 
    ## helper, to pass expensive object to function 
    f_helper = functools.partial(f, T) 
    # i've reduced count for tests 
    P = multiprocessing.Pool(processes=4) 
    results = P.map(f_helper, range(100)) 

    print results 
Verwandte Themen