No he visto ejemplos claros con casos de uso para Pool.apply , Pool.apply_async y Pool.map . Estoy usando principalmente Pool.map
; ¿Cuáles son las ventajas de los demás?
fuente
No he visto ejemplos claros con casos de uso para Pool.apply , Pool.apply_async y Pool.map . Estoy usando principalmente Pool.map
; ¿Cuáles son las ventajas de los demás?
En los viejos tiempos de Python, para llamar a una función con argumentos arbitrarios, usaría 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 multiprocessing.Pool
módulos 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
bloques hasta que se complete la función.
Pool.apply_async
también es como Python incorporado apply
, excepto que la llamada regresa inmediatamente en lugar de esperar el resultado. Se AsyncResult
devuelve un objeto. Llama a su get()
método para recuperar el resultado de la llamada a la función. El get()
método se bloquea hasta que se completa la función. Por lo tanto, pool.apply(func, args, kwargs)
es equivalente a pool.apply_async(func, args, kwargs).get()
.
En contraste con Pool.apply
, el Pool.apply_async
método también tiene una devolución de llamada que, si se proporciona, se llama cuando se completa la función. Esto se puede usar en lugar de llamar get()
.
Por 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]
Tenga en cuenta que, a diferencia pool.map
, el orden de los resultados puede no corresponder al orden en que se realizaron las pool.apply_async
llamadas.
Por lo tanto, si necesita ejecutar una función en un proceso separado, pero desea que el proceso actual se bloquee hasta que esa función regrese, use Pool.apply
. Como Pool.apply
, Pool.map
bloques hasta que se devuelva el resultado completo.
Si desea que el grupo de procesos de trabajo realice muchas llamadas de función de forma asincrónica, use Pool.apply_async
. El orden de los resultados no se garantiza que sea el mismo que el orden de las llamadas a Pool.apply_async
.
Observe también que puede llamar a varias funciones diferentes 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 Pool.apply_async
, los resultados se devuelven en un orden correspondiente al orden de los argumentos.
if __name__=="__main__"
antesapply_async_with_callback()
en Windows?Pool.map(func,iterable)
es equivalente aPool.map_async(func,iterable).get()
. Entonces, la relación entrePool.map
yPool.map_async
es similar a la dePool.apply
yPool.apply_async
. Losasync
comandos regresan inmediatamente, mientras que los que no sonasync
comandos bloquean. Losasync
comandos también tienen una devolución de llamada.Pool.map
yPool.apply
es similar a decidir cuándo usarmap
oapply
en Python. Simplemente usa la herramienta que se adapta al trabajo. Decidir entre usarasync
o no laasync
versión depende de si desea que la llamada bloquee el proceso actual y / o si desea usar la devolución de llamada.apply_async
devuelve unApplyResult
objeto. Llamando a queApplyResult
'sget
método devolverá el valor devuelto por la función asociada (o aumento de sueldomp.TimeoutError
si el tiempo de espera del call.) Así que si te ponen losApplyResult
s en una lista ordenada, a continuación, llamar a susget
métodos devolverá los resultados en el mismo orden.pool.map
Sin embargo, podría usar en esta situación.En cuanto a
apply
vsmap
:pool.apply(f, args)
:f
solo se ejecuta en UNO de los trabajadores de la agrupación. Por lo tanto, se ejecutará UNO de los procesos del grupof(args)
.pool.map(f, iterable)
: Este método corta el iterable en varios fragmentos que envía al grupo de procesos como tareas separadas. Entonces aprovecha todos los procesos en el grupo.fuente
apply_async()
8 veces? ¿Lo manejará automáticamente con una cola?He aquí un resumen en forma de tabla con el fin de mostrar las diferencias entre
Pool.apply
,Pool.apply_async
,Pool.map
yPool.map_async
. Al elegir uno, debe tener en cuenta los argumentos múltiples, la concurrencia, el bloqueo y los pedidos:Notas:
Pool.imap
yPool.imap_async
- versión más perezosa de map y map_async.Pool.starmap
método, muy similar al método de mapa además de la aceptación de múltiples argumentos.Async
Los métodos envían todos los procesos a la vez y recuperan los resultados una vez que han terminado. Use el método get para obtener los resultados.Pool.map
(oPool.apply
) los métodos son muy similares al mapa incorporado de Python (o se aplican). Bloquean el proceso principal hasta que todos los procesos se completen y devuelvan el resultado.Ejemplos:
mapa
Se solicita una lista de trabajos al mismo tiempo
aplicar
Solo se puede llamar para un trabajo
map_async
Se solicita una lista de trabajos al mismo tiempo
apply_async
Solo se puede llamar para un trabajo y ejecuta un trabajo en segundo plano en paralelo
mapa estelar
Es una variante de la
pool.map
cual soporta múltiples argumentosstarmap_async
Una combinación de starmap () y map_async () que itera sobre iterable de iterables y llama a func con los iterables desempaquetados. Devuelve un objeto de resultado.
Referencia:
Encuentre la documentación completa aquí: https://docs.python.org/3/library/multiprocessing.html
fuente