2012-06-19 10 views
5

Entonces, lo que trato de hacer es leer una línea, hacer algunos cálculos con la información en esa línea, luego agregar el resultado a algún objeto global, pero parece que nunca puedo obtenerlo trabajar. Por ejemplo, la prueba siempre es 0 en el siguiente código. Sé que esto está mal, y he tratado de hacerlo de otras maneras, pero todavía no está funcionando.cambiando la variable global al multiprocesamiento en 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 son generalmente una señal de que está haciendo algo mal. Aconsejo cambiar la forma en que funciona su programa para evitarlos: le ahorrará dolores de cabeza a largo plazo, y siempre hay una mejor manera. –

+0

El objetivo del módulo de multiprocesamiento es que genera procesos secundarios en lugar de hilos en el mismo proceso, con todos los intercambios habituales. Lamentablemente, la documentación no explica en absoluto los sacrificios, suponiendo que ya los conozca. Si sigue todas las "Pautas de programación" en la documentación, puede salirse con la suya sin comprender, pero realmente debería aprender. – abarnert

Respuesta

15

Los procesos de trabajo generados por el grupo obtienen su propia copia de la variable global y la actualizan. No comparten memoria a menos que lo configure explícitamente. La solución más fácil es comunicar el valor final de test al proceso principal, p. a través del valor de retorno. Algo así como (no probado ):

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 clave aquí es que, usando 'multiprocesamiento', los hilos (bueno, procesos) no comparten estado. –

+2

+1 para la respuesta y +1 @Lattyware. Desearía que la documentación de multiprocesamiento fuera un poco más clara sobre cómo los procesos de desove utilizando una API similar al módulo de subprocesamiento difieren de "la creación de subprocesos", porque eso resolvería la mitad de los problemas con el módulo en SO ... – abarnert

+0

¡Genial! Me ayudó a actualizar los modelos django. Aparentemente, la conexión no se bifurca y puede cerrarse incorrectamente por otro proceso. Para solucionar esto, utilicé este enfoque, pero no usé zip, acabo de acceder a los elementos tuple de la lista directamente usando un bucle for, y luego para cada elemento de la lista que pasa por la tupla usando tuple_element [index]. – radtek

0

Aquí es ejemplos del uso de variables globales dentro de multiprocesamiento.

podemos ver claramente que cada proceso funciona con su propia copia de la variable:

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)) 

Salida:

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