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?
fonte
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?
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.
if __name__=="__main__"
antesapply_async_with_callback()
no Windows?Pool.map(func,iterable)
é equivalente aPool.map_async(func,iterable).get()
. Portanto, a relação entrePool.map
ePool.map_async
é semelhante à dePool.apply
ePool.apply_async
. Osasync
comandos retornam imediatamente, enquanto os não-async
comandos bloqueiam. Osasync
comandos também têm um retorno de chamada.Pool.map
ePool.apply
é semelhante a decidir quando usarmap
ouapply
no Python. Você acabou de usar a ferramenta adequada ao trabalho. A decisão entre usar a versãoasync
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 umApplyResult
objeto. Chamando queApplyResult
'sget
método irá retornar o valor de retorno da função associada (ou raisemp.TimeoutError
se o tempo limite. Chamada) Então, se você colocar osApplyResult
s em uma lista ordenada, em seguida, chamando seusget
métodos irá retornar os resultados na mesma ordem. Você poderia apenas usarpool.map
nesta situação no entanto.Em relação a
apply
vsmap
:pool.apply(f, args)
:f
é executado apenas em UM dos trabalhadores da piscina. Portanto, um dos processos no pool será executadof(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.fonte
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
ePool.map_async
. Ao escolher um, você deve levar em consideração vários argumentos, simultaneidade, bloqueio e pedido:Notas:
Pool.imap
ePool.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
(ouPool.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.Exemplos:
mapa
É chamado para uma lista de trabalhos de uma só vez
Aplique
Só pode ser chamado para um emprego
map_async
É chamado para uma lista de trabalhos de uma só vez
apply_async
Só pode ser chamado para um trabalho e executa um trabalho em segundo plano em paralelo
mapa das estrelas
É uma variante da
pool.map
qual suporta vários argumentosstarmap_async
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.
Referência:
Encontre a documentação completa aqui: https://docs.python.org/3/library/multiprocessing.html
fonte