python: método de llamada sobre varias instancias en paralelo

Estoy tratando de llamar en paralelo al mismo método en varias instancias, donde las instancias se refieren al mismo objeto.

Lo siento por esta confusión declaraciones.

Específicamente, quiero cambiar el siguiente for-loop para ejecución paralela:

for i in range(len(instances)):#instances is a list of instances instances[i].do_some_computation_over_a_dataset() 

¿Es posible?

Nota para los futuros lectores:

El código anterior no es la forma de iterar sobre una colección de instancias en Python. Esto es cómo iterar de una manera secuencial (es decir, no paralela):

 for i in instances: i.do_some_computation_over_a_dataset() 

Bien, hagámoslo. Primero el código ( documentos de multiprocesamiento ):

 In [1]: from multiprocessing import Process In [2]: def f(): ...: print(1) ...: for i in range(100): ...: # do something ...: pass ...: In [3]: p1 = Process(target=f) In [4]: p1.start() 1 In [5]: p2 = Process(target=f) In [6]: p2.start() 1 In [7]: import time In [8]: def f(): ...: for i in range(100): ...: print(i) ...: # do something ...: time.sleep(1) ...: pass ...: In [9]: p1 = Process(target=f) In [9]: p1 = Process(target=f) In [10]: p1.start() 0 In [11]: p2 1 = Process(target=f)2 3 4 5 In [11]: p2 = Process(target=f) In [12]: 6 p2.7 start8 In [12]: p2.start() 0 In [13]: 9 

Este es un ejemplo de cómo una función puede ser llamada en paralelo. Desde In [10]: p1.start() puede ver que la salida se mezcla porque el progtwig p1 se ejecuta en paralelo mientras ejecutamos el progtwig p2.

Cuando ejecute el progtwig en un script de Python, querrá asegurarse de que el script solo finalice cuando todos los progtwigs se hayan ejecutado correctamente. Puedes hacer esto por

 def multi_process(instance_params, *funcs): process = [] for f in funcs: prog = Process(target=f, args=instance_params) prog.start() process.append(prog) for p in process: p.join() multi_process(params, f, f) 

Python no tiene C ++ o Java como soporte multithreading debido a GIL. Lea sobre esto aquí . Aunque si su progtwig es tal que realiza más operaciones de E / S y luego tareas intensivas de CPU, puede utilizar multihilo. Para realizar tareas intensivas de CPU se recomienda multiprocesamiento.

En el comentario @ytutow preguntó cuál es la diferencia entre el grupo de trabajadores y el proceso . De Pymotw :

La clase Pool se puede usar para administrar un número fijo de trabajadores en casos simples donde el trabajo a realizar se puede dividir y distribuir entre los trabajadores de forma independiente.

Los valores de retorno de los trabajos se recostackn y devuelven como una lista.

Los argumentos de la agrupación incluyen el número de procesos y una función que se ejecutará al iniciar el proceso de la tarea (se invoca una vez por hijo).

Puedes usar Pool como:

 def your_instance_method(instance): instances.do_some_computation_over_a_dataset() with Pool(3) as p: instances = [insatnce_1, instance_2, instance_3] print(p.map(your_instance_method, instances)) 

Sobre el número correcto de trabajadores, es una recomendación general tener 2 * número de cpu_cores de trabajadores.

Este código parece mostrar la diferencia entre un bucle for y un grupo, llamando a un método en diferentes instancias:

 from multiprocessing import Pool instances = ['a','ab','abc','abcd'] def calc_stuff(i): return len(i) if __name__ == '__main__': print('One at a time') for i in instances: print(len(i)) print('Use Pool') with Pool(4) as pool: print(pool.map(calc_stuff, instances)) 

Tenga en cuenta el uso de if __name__ == '__main':

Esto separa cada proceso.

Salida:

 One at a time 1 2 3 4 Use Pool [1, 2, 3, 4]