Eu tenho um script que executa com sucesso um conjunto de tarefas de pool de multiprocessamento com uma imap_unordered()
chamada:
p = multiprocessing.Pool()
rs = p.imap_unordered(do_work, xrange(num_tasks))
p.close() # No more work
p.join() # Wait for completion
No entanto, meu num_tasks
é cerca de 250.000 e, portanto, join()
bloqueia o thread principal por 10 segundos ou mais, e eu gostaria de poder ecoar na linha de comando de forma incremental para mostrar que o processo principal não está bloqueado. Algo como:
p = multiprocessing.Pool()
rs = p.imap_unordered(do_work, xrange(num_tasks))
p.close() # No more work
while (True):
remaining = rs.tasks_remaining() # How many of the map call haven't been done yet?
if (remaining == 0): break # Jump out of while loop
print "Waiting for", remaining, "tasks to complete..."
time.sleep(2)
Existe um método para o objeto de resultado ou o próprio pool que indica o número de tarefas restantes? Tentei usar um multiprocessing.Value
objeto como contador ( do_work
chama uma counter.value += 1
ação após realizar sua tarefa), mas o contador atinge apenas ~ 85% do valor total antes de parar o incremento.
fonte
def do_word(*a): time.sleep(.1)
como exemplo. Se não funcionar para você, crie um exemplo de código mínimo completo que demonstre seu problema: descreva usando palavras o que você espera que aconteça e o que acontece, mencione como você executa seu script Python, qual é o seu sistema operacional, versão Python e postar como uma nova pergunta .Pool.map()
. Eu não sabia que únicaimap()
eimap_unordered()
trabalho desta forma - a documentação apenas diz "Uma versão mais preguiçosos do mapa ()", mas realmente significa "o subjacente iterador retorna resultados como eles vêm".imap_unordered()
. O problema de Hanan é provavelmente devido asys.stderr.write('\r..')
(sobrescrever a mesma linha para mostrar o progresso).Meu favorito pessoal - oferece uma pequena barra de progresso e o ETA de conclusão enquanto as coisas são executadas e confirmadas em paralelo.
fonte
pip install tqdm
Descobri que o trabalho já estava feito quando tentei verificar o andamento. Isso é o que funcionou para mim usando o tqdm .
pip install tqdm
Isso deve funcionar com todos os tipos de multiprocessamento, sejam eles bloqueados ou não.
fonte
Encontrou uma resposta-me com um pouco mais de cavar: Tomando um olhar para o
__dict__
doimap_unordered
objeto de resultado, descobri que tem um_index
atributo que incrementos com cada conclusão da tarefa. Portanto, isso funciona para o registro, envolto nowhile
loop:No entanto, descobri que trocar o
imap_unordered
por ummap_async
resultou em uma execução muito mais rápida, embora o objeto de resultado seja um pouco diferente. Em vez disso, o objeto de resultado demap_async
tem um_number_left
atributo e umready()
método:fonte
rs
seja conhecido e é um pouco tarde ou não?rs
já lançou os outros threads.rs
em nenhum loop, sou novato em multiprocessamento e isso ajudaria. Muito obrigado.python 3.5
, a solução usando_number_left
não funciona._number_left
representa os pedaços que ainda precisam ser processados. Por exemplo, se eu quiser que 50 elementos sejam passados para minha função em paralelo, para um pool de threads com 3 processos,_map_async()
crie 10 chunks com 5 elementos cada._number_left
em seguida, representa quantos desses blocos foram concluídos.Eu sei que esta é uma questão bastante antiga, mas aqui está o que estou fazendo quando desejo acompanhar a progressão de um conjunto de tarefas em python.
Basicamente, você usa apply_async com um callbak (neste caso, é para anexar o valor retornado a uma lista), então você não precisa esperar para fazer outra coisa. Então, dentro de um loop while, você verifica a progressão do trabalho. Nesse caso, adicionei um widget para torná-lo mais bonito.
A saída:
Espero que ajude.
fonte
[pool.apply_async(my_function, (x,), callback=results.append) for x in dummy_args]
para(pool.apply_async(my_function, (x,), callback=results.append) for x in dummy_args)
Conforme sugerido por Tim, você pode usar
tqdm
eimap
para resolver esse problema. Acabei de descobrir esse problema e ajustei aimap_unordered
solução para poder acessar os resultados do mapeamento. Funciona assim:Caso você não se importe com os valores retornados de seus trabalhos, você não precisa atribuir a lista a nenhuma variável.
fonte
para quem procura uma solução simples trabalhando com
Pool.apply_async()
:fonte
Eu criei uma classe personalizada para criar uma impressão do progresso. Maby, isso ajuda:
fonte
Experimente esta abordagem simples baseada em Fila, que também pode ser usada com pool. Esteja ciente de que imprimir qualquer coisa após o início da barra de progresso fará com que ela seja movida, pelo menos para esta barra de progresso específica. (Progresso 1.5 do PyPI)
fonte