Isso pode ter sido perguntado em um contexto semelhante, mas não consegui encontrar uma resposta após cerca de 20 minutos de pesquisa, então vou perguntar.
Eu escrevi um script Python (digamos: scriptA.py) e um script (digamos scriptB.py)
No scriptB, quero chamar o scriptA várias vezes com argumentos diferentes, cada vez que leva cerca de uma hora para ser executado (é um script enorme, faz muitas coisas ... não se preocupe com isso) e quero ser capaz de executar o scriptA com todos os diferentes argumentos simultaneamente, mas preciso esperar até que TODOS eles sejam concluídos antes de continuar; meu código:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Eu quero executar tudo subprocess.call()
ao mesmo tempo e, em seguida, esperar até que tudo esteja pronto, como devo fazer isso?
Tentei usar threading como o exemplo aqui :
from threading import Thread
import subprocess
def call_script(args)
subprocess.call(args)
#run scriptA
t1 = Thread(target=call_script, args=(scriptA + argumentsA))
t2 = Thread(target=call_script, args=(scriptA + argumentsB))
t3 = Thread(target=call_script, args=(scriptA + argumentsC))
t1.start()
t2.start()
t3.start()
Mas eu não acho que isso esteja certo.
Como posso saber se todos eles terminaram de correr antes de ir para o meu do_finish()
?
fonte
join
blocos até que o thread termine a execução. Você terá que esperar por todos os threads de qualquer maneira. Set1
terminar primeiro, você começará a esperart2
(o que pode já ter sido concluído e você irá imediatamente prosseguir com a esperat3
). Set1
demorou mais para ser executado, quando você retornar dele, ambost1
et2
retornará imediatamente sem bloqueio.join
meio que anexa o processo atual ao thread e espera até que seja concluído, e se t2 terminar antes de t1 então quando t1 for feito ele irá verificar se t2 está sendo feito, veja que é e, em seguida, verifique t3..etc..etc .. e somente quando tudo estiver concluído, ele continuará. impressionante.Coloque os tópicos em uma lista e use o método Join
fonte
for x in threads: x.join()
de lista em vez de usarEm Python3, desde Python 3.2 há uma nova abordagem para chegar ao mesmo resultado, que eu pessoalmente prefiro ao pacote tradicional de criação / início / junção de thread
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlUsando um,
ThreadPoolExecutor
o código seria:A saída do código anterior é algo como:
Uma das vantagens é que você pode controlar a taxa de transferência configurando o máximo de workers simultâneos.
fonte
with
instrução é executado quando todas as tarefas são concluídas.with
instrução funciona por design neste caso. De qualquer forma, você sempre pode abrir uma nova pergunta no SO e postar seu código para que possamos ajudá-lo a descobrir o que está acontecendo no seu caso.concurrent.futures.wait
função, você pode ver um exemplo real aqui Documentos oficiais: docs.python.org/3/library/…Eu prefiro usar a compreensão de lista com base em uma lista de entrada:
fonte
for t in threads:t.start()
não é melhor?Você pode ter uma aula como abaixo, da qual você pode adicionar 'n' número de funções ou console_scripts que deseja executar paralelamente e iniciar a execução e esperar que todos os trabalhos sejam concluídos.
fonte
Da
threading
documentação do móduloEntão, para pegar aqueles dois casos em que você não está interessado em manter uma lista dos threads que você cria:
Portanto:
fonte
Talvez, algo como
fonte
Acabei de me deparar com o mesmo problema em que precisava esperar por todos os threads que foram criados usando o loop for. Acabei de experimentar o seguinte trecho de código. Pode não ser a solução perfeita, mas pensei que seria uma solução simples testar:
fonte