Dies wurde möglicherweise in einem ähnlichen Kontext gestellt, aber ich konnte nach etwa 20 Minuten Suche keine Antwort finden, daher werde ich fragen.
Ich habe ein Python-Skript (sagen wir: scriptA.py) und ein Skript (sagen wir scriptB.py) geschrieben.
In scriptB möchte ich scriptA mehrmals mit unterschiedlichen Argumenten aufrufen. Die Ausführung dauert jedes Mal ungefähr eine Stunde (es ist ein riesiges Skript, erledigt viele Dinge. Mach dir keine Sorgen) und ich möchte das ausführen können scriptA mit all den verschiedenen Argumenten gleichzeitig, aber ich muss warten, bis ALLE fertig sind, bevor ich fortfahre; Mein Code:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Ich möchte alle subprocess.call()
gleichzeitig laufen und dann warten, bis alle fertig sind. Wie soll ich das tun?
Ich habe versucht , wie das Beispiel zu verwenden Threading hier :
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()
Aber ich denke nicht, dass das richtig ist.
Woher weiß ich, dass sie alle fertig sind, bevor sie zu mir gehen do_finish()
?
quelle
join
blockiert, bis der Thread die Ausführung beendet hat. Sie müssen sowieso auf alle Threads warten. Wennt1
Sie zuerstt2
fertig sind, werden Sie mit dem Warten beginnen (was möglicherweise bereits beendet ist und Sie werden sofort darauf wartent3
). Wennt1
die Ausführung am längsten gedauert hat, kehren Sie beide zurückt1
undt2
kehren sofort ohne Blockierung zurück.join
hängt den aktuellen Prozess irgendwie an den Thread an und wartet, bis er fertig ist, und wenn t2 vor t1 endet, dann prüft es, wenn t1 fertig ist, ob t2 fertig ist das ist es, und dann überprüfen Sie t3..etc..etc .. und dann, wenn alle fertig sind, wird es fortgesetzt. genial.Fügen Sie die Threads in eine Liste ein und verwenden Sie dann die Join-Methode
quelle
for x in threads: x.join()
Listenverständnis machen würde, anstatt es zu verwendenIn Python3 gibt es seit Python 3.2 einen neuen Ansatz, um das gleiche Ergebnis zu erzielen, das ich persönlich dem herkömmlichen Paket zum Erstellen / Starten / Verbinden von Threads vorziehe
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlDie Verwendung eines
ThreadPoolExecutor
Codes wäre:Die Ausgabe des vorherigen Codes ist ungefähr so:
Einer der Vorteile besteht darin, dass Sie den Durchsatz steuern können, indem Sie die maximale Anzahl gleichzeitiger Mitarbeiter festlegen.
quelle
with
Anweisung ausgeführt, wenn alle Aufgaben abgeschlossen sind.with
diesem Fall funktioniert die Anweisung so , wie sie beabsichtigt ist . Auf jeden Fall können Sie jederzeit eine neue Frage in SO öffnen und Ihren Code veröffentlichen, damit wir Ihnen helfen können, herauszufinden, was in Ihrem Fall passiert.concurrent.futures.wait
Funktion verwenden, Sie können ein echtes Beispiel hier sehen Offizielle Dokumente: docs.python.org/3/library/…Ich bevorzuge das Listenverständnis basierend auf einer Eingabeliste:
quelle
for t in threads:t.start()
ist es nicht besser?Sie können eine Klasse wie die folgende haben, aus der Sie 'n' Funktionen oder Konsolenskripte hinzufügen können, die Sie parallel ausführen möchten, die Ausführung starten und warten, bis alle Jobs abgeschlossen sind.
quelle
Aus der
threading
ModuldokumentationSo fangen Sie diese beiden Fälle ab, wenn Sie nicht daran interessiert sind, eine Liste der von Ihnen erstellten Threads zu führen:
Worauf:
quelle
Vielleicht so etwas wie
quelle
Ich bin gerade auf dasselbe Problem gestoßen, bei dem ich auf alle Threads warten musste, die mit der for-Schleife erstellt wurden. Ich habe gerade den folgenden Code ausprobiert. Es ist möglicherweise nicht die perfekte Lösung, aber ich dachte, es wäre eine einfache Lösung zu testen:
quelle