La matriz compartida no se comparte correctamente en el multiprocesamiento de Python

Estoy experimentando multiprocesamiento en Python e intenté compartir una matriz de cadenas entre dos procesos. Aquí está mi código de python:

from multiprocessing import Process, Array, Value import ctypes def f1(a, v): for i, l in enumerate(['a', 'b', 'c']): a[i] = l*3 v.value += 1 print "f1 : ", a[:], v.value def f2(a,v): v.value += 1 print "f2 : ", a[:], v.value if __name__ == '__main__': val = Value(ctypes.c_int, 0) arr = Array(ctypes.c_char_p, 3) print "Before :", arr[:], val.value p = Process(target=f1, args=(arr, val)) p2 = Process(target=f2, args=(arr, val)) p.start() p2.start() p.join() p2.join() print "After : ", arr[:], val.value 

Cuando ejecuto el script, veo que arr está correctamente poblado y disponible en f1() pero no en f2() . Aquí está el resultado:

  % python /tmp/tests.py Before : [None, None, None] 0 f1 : ['aaa', 'bbb', 'ccc'] 1 f2 : ['\x01', '\x11', '\x01'] 2 After : ['\x01', '\x01', '\x01'] 2 

¿Pasé por alto algo?

Gracias de antemano por tu colaboración. 🙂

Mi suposicion es:

arr almacena 3 punteros. f1() asigna a direcciones de memoria que no tienen ningún significado fuera del proceso actual. f2() intenta acceder a las direcciones sin sentido que contienen basura en este punto.

Asignar valores que tienen significado en todos los procesos parece ayudar:

 from __future__ import print_function import ctypes import time from multiprocessing import Process, Array, Value values = [(s*4).encode('ascii') for s in 'abc'] def f1(a, v): for i, s in enumerate(values): a[i] = s v.value += 1 print("f1 : ", a[:], v.value) def f2(a,v): v.value += 1 print("f2 : ", a[:], v.value) def main(): val = Value(ctypes.c_int, 0) arr = Array(ctypes.c_char_p, 3) print("Before :", arr[:], val.value) p = Process(target=f1, args=(arr, val)) p2 = Process(target=f2, args=(arr, val)) p.start() p2.start() p.join() p2.join() print("After : ", arr[:], val.value) if __name__ == '__main__': main() 

Salida

 Before : [None, None, None] 0 f1 : ['aaaa', 'bbbb', 'cccc'] 1 f2 : ['aaaa', 'bbbb', 'cccc'] 2 After : ['aaaa', 'bbbb', 'cccc'] 2 

No tengo una solución, pero puedo agregar más sugerencias. He eliminado el guión para señalar el problema. Me parece que el problema está en la operación l * 3 . No sé por qué, pero mover la operación l * 3 en el enumerator funciona como se esperaba:

 from multiprocessing import Process, Array import ctypes def f1(a): # for i, l in enumerate(['a', 'b', 'c']): # a[i] = (l * 3) for i, l in enumerate(['a' * 3, 'b' * 3, 'c' * 3]): a[i] = l print "f1 : ", map(id, a), a[:] if __name__ == '__main__': arr = Array(ctypes.c_char_p, 3) print "Before :", map(id, arr), arr[:] p = Process(target=f1, args=(arr, )) p.start() p.join() print "After : ", map(id, arr), arr[:] 

Resultado:

 Before : [3077673516L, 3077673516L, 3077673516L] [None, None, None] f1 : [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc'] After : [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc']