Questo (ad esempio enormemente semplificato) funziona bene (Python 2.6.6, Debian Squeeze):Modelli di utilizzo alternativi per il multiprocesso di Python che evita la proliferazione dello stato globale?
from multiprocessing import Pool
import numpy as np
src=None
def process(row):
return np.sum(src[row])
def main():
global src
src=np.ones((100,100))
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
tuttavia, dopo anni di essere insegnato stato globale male !!!, tutti i miei istinti mi dicono io davvero preferirei scriverò qualcosa di più vicino:
from multiprocessing import Pool
import numpy as np
def main():
src=np.ones((100,100))
def process(row):
return np.sum(src[row])
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
ma, naturalmente, che non funziona (si blocca fino incapace di salamoia qualcosa).
L'esempio qui è banale, ma quando si aggiungono più funzioni "di processo" e ognuna di queste dipende da più ingressi aggiuntivi ... beh, tutto diventa un po 'reminescente di qualcosa scritto in BASIC 30 anni fa . Cercare di utilizzare le classi per aggregare almeno lo stato con le funzioni appropriate sembra una soluzione ovvia, ma in pratica lo doesn't seem to be that easy.
C'è qualche schema o stile consigliato per l'utilizzo di multiprocessing.pool che eviterà la proliferazione dello stato globale per supportare ogni funzione su cui voglio eseguire la mappatura parallela?
In che modo i "professionisti multiprocessing" esperti si occupano di questo?
Aggiornamento: Notare che sono effettivamente interessati nella lavorazione molto array più grandi, così variazioni sul sopra del quale sottaceto src
ogni chiamata/iterazione non sono altrettanto buono come quelli che forcella in processi di lavoro del pool.
Io non sono un esperto multiprocessing pro o altro, ma lasciate che vi chiedo perché non si può semplicemente fare pool.map (processo, prodotto ([src], intervallo (100))) e cambiare la funzione del processo per accettare entrambe le variabili come argomenti? Anche questo è altamente inefficiente? – luke14free
@ luke14free: Sì, questo avrebbe messo sottosopra l'array src per ogni chiamata, e in realtà sono interessato a matrici/dati molto più grandi di quelli nel codice di esempio qui sopra, quindi non ideale. Con il pool di processi, qualsiasi stato viene impostato nel punto in cui il pool viene creato viene biforcato nei processi di lavoro e disponibile per essere letto "gratuitamente". L'idea contribuirebbe a evitare di inserire in "globals" anche uno stato di "variabili di controllo" minori (ad esempio bandiere), grazie. – timday