Cela a peut-être été demandé dans un contexte similaire, mais je n'ai pas pu trouver de réponse après environ 20 minutes de recherche, je vais donc demander.
J'ai écrit un script Python (disons: scriptA.py) et un script (disons scriptB.py)
Dans scriptB, je veux appeler scriptA plusieurs fois avec des arguments différents, chaque fois prend environ une heure à exécuter, (c'est un énorme script, fait beaucoup de choses ... ne vous inquiétez pas) et je veux pouvoir exécuter le scriptA avec tous les différents arguments simultanément, mais je dois attendre que TOUS soient terminés avant de continuer; mon code:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Je veux tout exécuter subprocess.call()
en même temps, puis attendre qu'ils soient tous terminés, comment dois-je faire cela?
J'ai essayé d'utiliser le filetage comme l'exemple ici :
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()
Mais je ne pense pas que ce soit juste.
Comment puis-je savoir qu'ils ont tous fini de courir avant d'accéder à mon do_finish()
?
la source
join
blocs jusqu'à ce que le thread termine l'exécution. Vous devrez de toute façon attendre tous les threads. Si set1
termine en premier, vous commencerez à attendret2
(ce qui est peut-être déjà terminé et vous passerez immédiatement à attendret3
). Si cela at1
pris le plus de temps à exécuter, lorsque vous en revenez à la foist1
ett2
que vous reviendrez immédiatement sans blocage.join
j'étais un peu confus à ce sujet mais je pense que je comprends, en quelque sorte attache le processus actuel au thread et attend que ce soit fait, et si t2 se termine avant t1, alors lorsque t1 est terminé, il vérifiera que t2 est terminé, voir que c'est le cas, puis vérifiez t3..etc..etc .. et alors seulement quand tout est fait, il continuera. impressionnant.Mettez les threads dans une liste, puis utilisez la méthode Join
la source
for x in threads: x.join()
compilation de liste plutôt que d'utiliser la compilation de listesEn python3, depuis Python 3.2 , il est une nouvelle approche pour atteindre le même résultat, que je préfère personnellement à la création de fil traditionnelle / start / join, package
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlUtiliser un
ThreadPoolExecutor
code serait:La sortie du code précédent est quelque chose comme:
L'un des avantages est que vous pouvez contrôler le débit en définissant le nombre maximal de nœuds de calcul simultanés.
la source
with
instruction est exécuté lorsque toutes les tâches sont terminées.with
instruction fonctionne par conception dans ce cas. Quoi qu'il en soit, vous pouvez toujours ouvrir une nouvelle question dans SO et publier votre code afin que nous puissions vous aider à découvrir ce qui se passe dans votre cas.concurrent.futures.wait
fonction, vous pouvez voir un exemple réel ici DocumentsJe préfère utiliser la compréhension de liste basée sur une liste d'entrée:
la source
for t in threads:t.start()
n'est-ce pas mieux?Vous pouvez avoir une classe quelque chose comme ci-dessous à partir de laquelle vous pouvez ajouter un nombre 'n' de fonctions ou de console_scripts que vous souhaitez exécuter en parallèle avec passion et démarrer l'exécution et attendre que tous les travaux soient terminés.
la source
À partir de la documentation du
threading
moduleDonc, pour attraper ces deux cas où vous n'êtes pas intéressé à conserver une liste des threads que vous créez:
Après quoi:
la source
Peut-être, quelque chose comme
la source
Je viens de rencontrer le même problème où je devais attendre tous les threads créés à l'aide de la boucle for.Je viens d'essayer le morceau de code suivant.Ce n'est peut-être pas la solution parfaite mais je pensais que ce serait une solution simple tester:
la source