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)
applyainda 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.Poolmódulos tentam fornecer uma interface semelhante.
Pool.applyé como Python apply, exceto que a chamada da função é realizada em um processo separado. Pool.applybloqueia até que a função seja concluída.
Pool.apply_asynctambém é como o built-in do Python apply, exceto que a chamada retorna imediatamente em vez de esperar pelo resultado. Um AsyncResultobjeto é 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_asyncmé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_asyncchamadas 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.mapbloqueia 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.mapaplica 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.mape Pool.map_asyncé semelhante à de Pool.applye Pool.apply_async. Os asynccomandos retornam imediatamente, enquanto os não- asynccomandos bloqueiam. Os asynccomandos também têm um retorno de chamada.
Pool.mape Pool.applyé semelhante a decidir quando usar mapou applyno Python. Você acabou de usar a ferramenta adequada ao trabalho. A decisão entre usar a versão asynce a não- asyncversão depende se você deseja que a chamada bloqueie o processo atual e / ou se você deseja usar o retorno de chamada.
apply_asyncretorna um ApplyResultobjeto. Chamando que ApplyResult's getmétodo irá retornar o valor de retorno da função associada (ou raise mp.TimeoutErrorse o tempo limite. Chamada) Então, se você colocar os ApplyResults em uma lista ordenada, em seguida, chamando seus getmétodos irá retornar os resultados na mesma ordem. Você poderia apenas usar pool.mapnesta situação no entanto.
Em relação a applyvs 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.mape 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.imape 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.
AsyncOs 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.mapqual 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?