2012-11-30 7 views
5

Uso il multiprocessing nel mio progetto. Ho una funzione worker che mette in coda i risultati. Tutto funziona bene Ma come aumenta la dimensione di x (nel mio caso x è un array) qualcosa è andato storto. Qui è una versione semplificata del mio codice:Elaborazione multipla in python bloccata

def do_work(queue, x): 
    result = heavy_computation_function(x) 
    queue.put(result) # PROBLEM HERE 

def parallel_something(): 
    queue = Queue() 
    procs = [Process(target=do_work, args=i) for i in xrange(20)] 
    for p in procs: p.start() 
    for p in procs: p.join() 

    results = [] 
    while not queue.empty(): 
     results.append(queue.get) 

    return results 

vedo nel sistema monitorare i processi di pitone di lavoro, ma poi qualcosa accadrà e tutti i processi sono in esecuzione, ma non fare nulla. Questo è ciò che ottengo quando digito ctrl-D.

pid, sts = os.waitpid(self.pid, flag) 
KeyboardInterrupt 

Faccio qualche test. E il problema sembra essere nel mettere i risultati in coda, infatti se non metto i risultati tutto funziona, ma poi non ci sarebbe alcuno scopo.

+4

Sembra non passare mai l'oggetto coda al nuovo processo. Anche 'args' di' Process' dovrebbe essere una 'tupla'. Prova a cambiarlo in 'args = (queue, i)'. Il tuo 'queue.get' richiede anche alcune parentesi in modo che diventi' queue.get() '. – Wessie

risposta

3

Bene, sembra che ci sia qualche bug nel modulo Queue di python. Infatti utilizzando ..

from multiprocessing import Manager 

queue = Manager().Queue() 

..everything opere, ma io ancora non so perché .. :)

+0

La differenza è che si sta istanziando 'Manager(). Queue()' invece di semplicemente 'Queue()'. Penso che questo significhi che 'Manager .__ init __()' viene chiamato nel primo modulo ma non nel secondo. – Patrick

5

Siete probabilmente generando una situazione di stallo.

Dal programming guidelines:

Questo significa che ogni volta che si utilizza una coda è necessario fare in modo che tutti gli elementi che sono stati messi in coda alla fine saranno rimossi prima che il processo si unisce. Altrimenti non puoi essere sicuro che i processi che hanno messo gli articoli in coda finiranno. Ricorda anche che i processi non demoniaci saranno uniti automaticamente.

Una possibile soluzione è proposta anche nella pagina. Tieni presente che se i processi non vengono uniti, ciò non significa che stanno "occupando" le risorse in alcun senso. Ciò significa che è possibile ottenere i dati in coda dopo che i processi hanno completato la loro operazione (forse usando locks) e solo successivamente unire i processi.