multiprocesamiento.Pool: ¿Cuándo usar apply, apply async o map?


No he visto ejemplos claros con casos de uso para Pool.aplicar, Piscina.apply_async y Pool.map . Estoy usando principalmente Pool.map; ¿cuáles son las ventajas de los demás?

Author: martineau, 2011-12-16

2 answers

En los viejos tiempos de Python, para llamar a una función con argumentos arbitrarios, usarías apply:

apply(f,args,kwargs)

apply todavía existe en Python2. 7 aunque no en Python3, y generalmente ya no se usa. Hoy en día,

f(*args,**kwargs)
Se prefiere

. Los módulos multiprocessing.Pool intentan proporcionar una interfaz similar.

Pool.apply es como Python apply, excepto que la llamada a la función se realiza en un proceso separado. Pool.apply bloquea hasta que se completa la función.

Pool.apply_async es también como el incorporado en Python apply, excepto que la llamada regresa inmediatamente en lugar de esperar el resultado. Se devuelve un objeto ApplyResult. Llama a su método get() para recuperar el resultado de la llamada a la función. El método get() se bloquea hasta que se completa la función. Así, pool.apply(func, args, kwargs) es equivalente a pool.apply_async(func, args, kwargs).get().

En contraste con Pool.apply, el método Pool.apply_async también tiene una devolución de llamada que, si se suministra, se llama cuando la función está completa. Esto se puede usar en lugar de llamar a get().

Para ejemplo:

import multiprocessing as mp
import time

def foo_pool(x):
    time.sleep(2)
    return x*x

result_list = []
def log_result(result):
    # This is called whenever foo_pool(i) returns a result.
    # result_list is modified only by the main process, not the pool workers.
    result_list.append(result)

def apply_async_with_callback():
    pool = mp.Pool()
    for i in range(10):
        pool.apply_async(foo_pool, args = (i, ), callback = log_result)
    pool.close()
    pool.join()
    print(result_list)

if __name__ == '__main__':
    apply_async_with_callback()

Puede producir un resultado como

[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]

Observe, a diferencia de pool.map, el orden de los resultados puede no corresponder al orden en el que se hicieron las llamadas pool.apply_async.


Por lo tanto, si necesita ejecutar una función en un proceso separado, pero desea que el proceso actual bloquee hasta que regrese esa función, use Pool.apply. Like Pool.apply, Pool.map bloquea hasta que se devuelve el resultado completo.

Si desea que el Grupo de procesos de trabajo realice muchos llamadas de función asíncronas, utilice Pool.apply_async. No se garantiza que el orden de los resultados sea el mismo que el orden de las llamadas a Pool.apply_async.

Observe también que puede llamar a un número de diferentes funciones con Pool.apply_async (no todas las llamadas necesitan usar la misma función).

En contraste, Pool.map aplica la misma función a muchos argumentos. Sin embargo, a diferencia de Pool.apply_async, los resultados se devuelven en un orden correspondiente al orden de los argumentos.

 306
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-16 18:59:29

Respecto a apply vs map:

pool.apply(f, args): f solo se ejecuta en UNO de los trabajadores de la piscina. Así que UNO de los procesos del pool se ejecutará f(args).

pool.map(f, iterable): Este método corta el iterable en un número de trozos que envía al grupo de procesos como tareas separadas. Así que usted toma ventaja de todos los procesos en el grupo.

 58
Author: kakhkAtion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-18 16:55:52