Python: cómo utilizar el valor y la matriz en el grupo de multiprocesamiento

Para multiprocessing con Process , puedo usar Value, Array configurando args param.

Con multiprocessing con Pool , ¿cómo puedo usar Value, Array. No hay nada en los documentos sobre cómo hacer esto.

 from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in range(len(a)): a[i] = -a[i] if __name__ == '__main__': num = Value('d', 0.0) arr = Array('i', range(10)) p = Process(target=f, args=(num, arr)) p.start() p.join() print(num.value) print(arr[:]) 

Estoy tratando de usar Value, Array dentro del fragmento de código a continuación.

 import multiprocessing def do_calc(data): # access num or # work to update arr newdata =data * 2 return newdata def start_process(): print 'Starting', multiprocessing.current_process().name if __name__ == '__main__': num = Value('d', 0.0) arr = Array('i', range(10)) inputs = list(range(10)) print 'Input :', inputs pool_size = multiprocessing.cpu_count() * 2 pool = multiprocessing.Pool(processes=pool_size,initializer=start_process, ) pool_outputs = pool.map(do_calc, inputs) pool.close() # no more tasks pool.join() # wrap up current tasks print 'Pool :', pool_outputs 

Nunca supe “la razón” de esto, pero el multiprocessing ( mp ) utiliza diferentes mecanismos de selección / desactivación para las funciones pasadas a la mayoría Pool métodos de Pool . Es una consecuencia que los objetos creados por elementos como mp.Value , mp.Array , mp.Lock , …, no se pueden pasar como argumentos a tales métodos, aunque se pueden pasar como argumentos a mp.Process y al Función de initializer opcional de mp.Pool() . Por esto último, esto funciona:

 import multiprocessing as mp def init(aa, vv): global a, v a = aa v = vv def worker(i): a[i] = v.value * i if __name__ == "__main__": N = 10 a = mp.Array('i', [0]*N) v = mp.Value('i', 3) p = mp.Pool(initializer=init, initargs=(a, v)) p.map(worker, range(N)) print(a[:]) 

y que imprime

 [0, 3, 6, 9, 12, 15, 18, 21, 24, 27] 

Esa es la única forma que conozco para que esto funcione en todas las plataformas.

En las plataformas Linux-y (donde mp crea nuevos procesos a través de fork() ), puede crear en su lugar los mp.Array y mp.Value (etc) como módulos globales en cualquier momento antes de hacer mp.Pool() . Los procesos creados por fork() heredan todo lo que se encuentra en el espacio global de direcciones del módulo en el momento en que se ejecuta mp.Pool() .

Pero eso no funciona en absoluto en plataformas (lea “Windows”) que no son compatibles con fork() .