Não vi exemplos claros com casos de uso para Pool.apply , Pool.apply_async e Pool.map . Eu estou usando principalmente Pool.map
; quais são as vantagens dos outros?
Não vi exemplos claros com casos de uso para Pool.apply , Pool.apply_async e Pool.map . Eu estou usando principalmente Pool.map
; quais são as vantagens dos outros?
Respostas:
Nos velhos tempos do Python, para chamar uma função com argumentos arbitrários, você usaria apply
:
apply(f,args,kwargs)
apply
ainda existe no Python2.7, embora não no Python3, e geralmente não é mais usado. Hoje em dia,
f(*args,**kwargs)
é preferível. Os multiprocessing.Pool
módulos tentam fornecer uma interface semelhante.
Pool.apply
é como Python apply
, exceto que a chamada da função é realizada em um processo separado. Pool.apply
bloqueia até que a função seja concluída.
Pool.apply_async
também é como o built-in do Python apply
, exceto que a chamada retorna imediatamente em vez de esperar pelo resultado. Um AsyncResult
objeto é retornado. Você chama seu get()
método para recuperar o resultado da chamada de função. O get()
método bloqueia até que a função seja concluída. Assim, pool.apply(func, args, kwargs)
é equivalente a pool.apply_async(func, args, kwargs).get()
.
Por outro lado Pool.apply
, o Pool.apply_async
método também possui um retorno de chamada que, se fornecido, é chamado quando a função é concluída. Isso pode ser usado em vez de chamar get()
.
Por exemplo:
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()
pode produzir um resultado como
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Observe que, diferentemente pool.map
, a ordem dos resultados pode não corresponder à ordem em que as pool.apply_async
chamadas foram feitas.
Portanto, se você precisar executar uma função em um processo separado, mas desejar que o processo atual seja bloqueado até que a função retorne, use Pool.apply
. Como Pool.apply
, Pool.map
bloqueia até que o resultado completo seja retornado.
Se você deseja que o conjunto de processos do operador execute várias chamadas de função de forma assíncrona, use Pool.apply_async
. A ordem dos resultados não é garantida como a ordem das chamadas para Pool.apply_async
.
Observe também que você pode chamar várias funções diferentesPool.apply_async
(nem todas as chamadas precisam usar a mesma função).
Por outro lado, Pool.map
aplica a mesma função a muitos argumentos. No entanto, diferentemente Pool.apply_async
, os resultados são retornados em uma ordem correspondente à ordem dos argumentos.
Pool.map(func,iterable)
é equivalente a Pool.map_async(func,iterable).get()
. Portanto, a relação entre Pool.map
e Pool.map_async
é semelhante à de Pool.apply
e Pool.apply_async
. Os async
comandos retornam imediatamente, enquanto os não- async
comandos bloqueiam. Os async
comandos também têm um retorno de chamada.
Pool.map
e Pool.apply
é semelhante a decidir quando usar map
ou apply
no Python. Você acabou de usar a ferramenta adequada ao trabalho. A decisão entre usar a versão async
e a não- async
versão depende se você deseja que a chamada bloqueie o processo atual e / ou se você deseja usar o retorno de chamada.
apply_async
retorna um ApplyResult
objeto. Chamando que ApplyResult
's get
método irá retornar o valor de retorno da função associada (ou raise mp.TimeoutError
se o tempo limite. Chamada) Então, se você colocar os ApplyResult
s em uma lista ordenada, em seguida, chamando seus get
métodos irá retornar os resultados na mesma ordem. Você poderia apenas usar pool.map
nesta situação no entanto.
Em relação a apply
vs map
:
pool.apply(f, args)
: f
é executado apenas em UM dos trabalhadores da piscina. Portanto, um dos processos no pool será executado f(args)
.
pool.map(f, iterable)
: Esse método divide o iterável em vários pedaços que ele envia ao pool de processos como tarefas separadas. Então você tira proveito de todos os processos no pool.
apply_async()
8 vezes? Ele irá lidar automaticamente com uma fila?
Aqui está uma visão geral em formato de tabela, a fim de mostrar as diferenças entre Pool.apply
, Pool.apply_async
, Pool.map
e Pool.map_async
. Ao escolher um, você deve levar em consideração vários argumentos, simultaneidade, bloqueio e pedido:
| 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
e Pool.imap_async
- versão mais lenta do mapa e map_async.
Pool.starmap
método, muito semelhante ao método map, além da aceitação de vários argumentos.
Async
Os métodos enviam todos os processos de uma só vez e recuperam os resultados assim que terminam. Use o método get para obter os resultados.
Pool.map
(ou Pool.apply
) métodos são muito semelhantes ao mapa interno do Python (ou aplicam-se). Eles bloqueiam o processo principal até que todos os processos sejam concluídos e retornem o resultado.
É chamado para uma lista de trabalhos de uma só vez
results = pool.map(func, [1, 2, 3])
Só pode ser chamado para um emprego
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
É chamado para uma lista de trabalhos de uma só vez
pool.map_async(func, jobs, callback=collect_result)
Só pode ser chamado para um trabalho e executa um trabalho em segundo plano em paralelo
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
É uma variante da pool.map
qual suporta vários argumentos
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Uma combinação de starmap () e map_async () que itera sobre iterável de iterables e chama func com os iterables descompactados. Retorna um objeto de resultado.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Encontre a documentação completa aqui: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
antesapply_async_with_callback()
no Windows?