2012-06-19 22 views
5

Quindi quello che sto cercando di fare in definitiva è leggere una riga, fare alcuni calcoli con le informazioni in quella linea, quindi aggiungere il risultato a qualche oggetto globale, ma non riesco mai a ottenerlo lavorare. Ad esempio, il test è sempre 0 nel codice qui sotto. So che questo è sbagliato, e ho provato a farlo in altri modi, ma non funziona ancora.modifica della variabile globale durante la multiprocessing in python

import multiprocessing as mp 

File = 'HGDP_FinalReport_Forward.txt' 
#short_file = open(File) 
test = 0 

def pro(temp_line): 
    global test 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return len(temp_line) 

if __name__ == "__main__": 
    with open("HGDP_FinalReport_Forward.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     t = pool.map(pro,lines.readlines()) 
+2

Globals sono in genere un segno che si sta facendo qualcosa di sbagliato. Ti consiglio di cambiare il modo in cui il tuo programma funziona per evitarli, ma a lungo andare ti farà risparmiare grattacapi e c'è sempre un modo migliore. –

+0

Il punto del modulo multiprocessing è che genera processi figlio anziché thread nello stesso processo, con tutti i soliti compromessi. Sfortunatamente, la documentazione non spiega affatto questi compromessi, presumendo che tu li conosca già. Se segui tutte le "Linee guida per la programmazione" nella documentazione, potresti non capire, ma dovresti davvero imparare. – abarnert

risposta

15

I processi di lavoro generati dal pool ottengono la propria copia della variabile globale e la aggiornano. Non condividono la memoria a meno che non lo imposti esplicitamente. La soluzione più semplice è quella di comunicare il valore finale di test al processo principale, ad es. tramite il valore di ritorno. Qualcosa di simile (non testata ):

def pro(temp_line): 
    test = 0 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return test, len(temp_line) 

if __name__ == "__main__": 
    with open("somefile.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     tests_and_t = pool.map(pro,lines.readlines()) 
     tests, t = zip(*test_and_t) 
     test = sum(tests) 
+8

La cosa fondamentale qui è che, usando 'multiprocessing', i thread (beh, i processi) non condividono lo stato. –

+2

+1 per la risposta e +1 @Lattyware. Vorrei che la documentazione di multiprocessing fosse un po 'più chiara su come "i processi di spawning usando un'API simile al modulo di threading" differisce da "creare thread", perché risolverebbe metà dei problemi con il modulo su SO ... – abarnert

+0

Grandi cose! Mi ha aiutato con l'aggiornamento dei modelli di Django. Apparentemente la connessione non è biforcuta e può essere chiusa in modo improprio da un altro processo. Per prendermi cura di questo ho usato questo approccio ma non ho usato zip, ho appena avuto accesso agli elementi tuple dalla lista usando direttamente un ciclo for, e quindi per ogni elemento della lista che passa attraverso la tupla usando tuple_element [index]. – radtek

0

Ecco alcuni esempi di utilizzo variabile globale all'interno di multiprocessing.

possiamo vedere chiaramente che ogni processo funziona con la propria copia di variabili:

import multiprocessing 
import time 
import os 
import sys 
import random 
def worker(a): 
    oldValue = get() 
    set(random.randint(0, 100)) 
    sys.stderr.write(' '.join([str(os.getpid()), str(a), 'old:', str(oldValue), 'new:', str(get()), '\n'])) 

def get(): 
    global globalVariable 
    return globalVariable 

globalVariable = -1 
def set(v): 
    global globalVariable 
    globalVariable = v 

print get() 
set(-2) 
print get() 

processPool = multiprocessing.Pool(5) 
results = processPool.map(worker, range(15)) 

uscita:

27094 0 old: -2 new: 2 
27094 1 old: 2 new: 95 
27094 2 old: 95 new: 20 
27094 3 old: 20 new: 54 
27098 4 old: -2 new: 80 
27098 6 old: 80 new: 62 
27095 5 old: -2 new: 100 
27094 7 old: 54 new: 23 
27098 8 old: 62 new: 67 
27098 10 old: 67 new: 22 
27098 11 old: 22 new: 85 
27095 9 old: 100 new: 32 
27094 12 old: 23 new: 65 
27098 13 old: 85 new: 60 
27095 14 old: 32 new: 71 
Problemi correlati