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?
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?
Respuestas:
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.
Pool.map(func,iterable)
es equivalente a Pool.map_async(func,iterable).get()
. Entonces, la relación entre Pool.map
y Pool.map_async
es similar a la de Pool.apply
y Pool.apply_async
. Los async
comandos regresan inmediatamente, mientras que los que no son async
comandos bloquean. Los async
comandos también tienen una devolución de llamada.
Pool.map
y Pool.apply
es similar a decidir cuándo usar map
o apply
en Python. Simplemente usa la herramienta que se adapta al trabajo. Decidir entre usar async
o no la async
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 un ApplyResult
objeto. Llamando a que ApplyResult
's get
método devolverá el valor devuelto por la función asociada (o aumento de sueldo mp.TimeoutError
si el tiempo de espera del call.) Así que si te ponen los ApplyResult
s en una lista ordenada, a continuación, llamar a sus get
métodos devolverá los resultados en el mismo orden. pool.map
Sin embargo, podría usar en esta situación.
En cuanto a apply
vs map
:
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 grupo f(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.
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
y Pool.map_async
. Al elegir uno, debe tener en cuenta los argumentos múltiples, la concurrencia, el bloqueo y los pedidos:
| Multi-args Concurrence Blocking Ordered-results
---------------------------------------------------------------------
Pool.map | no yes yes yes
Pool.map_async | no yes no yes
Pool.apply | yes no yes no
Pool.apply_async | yes yes no no
Pool.starmap | yes yes yes yes
Pool.starmap_async| yes yes no no
Pool.imap
y Pool.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
(o Pool.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.
Se solicita una lista de trabajos al mismo tiempo
results = pool.map(func, [1, 2, 3])
Solo se puede llamar para un trabajo
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Se solicita una lista de trabajos al mismo tiempo
pool.map_async(func, jobs, callback=collect_result)
Solo se puede llamar para un trabajo y ejecuta un trabajo en segundo plano en paralelo
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
Es una variante de la pool.map
cual soporta múltiples argumentos
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
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.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Encuentre la documentación completa aquí: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
antesapply_async_with_callback()
en Windows?