Wenn ich einen Thread in einer Endlosschleife habe, gibt es eine Möglichkeit, ihn zu beenden, wenn das Hauptprogramm endet (z. B. wenn ich Ctrl+ drücke C)?
84
Wenn ich einen Thread in einer Endlosschleife habe, gibt es eine Möglichkeit, ihn zu beenden, wenn das Hauptprogramm endet (z. B. wenn ich Ctrl+ drücke C)?
Überprüfen Sie diese Frage. Die richtige Antwort enthält eine gute Erklärung, wie Threads richtig beendet werden können: Gibt es eine Möglichkeit, einen Thread in Python zu beenden ?
Um den Thread beim Keyboard Interrupt-Signal (Strg + C) anzuhalten, können Sie die Ausnahme "KeyboardInterrupt" abfangen und vor dem Beenden bereinigen. So was:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
Auf diese Weise können Sie steuern, was zu tun ist, wenn das Programm abrupt beendet wird.
Sie können auch das integrierte Signalmodul verwenden, mit dem Sie Signalhandler einrichten können (in Ihrem speziellen Fall das SIGINT-Signal): http://docs.python.org/library/signal.html
cleanup_stop_thread()
eine globale Funktion, die ich verwenden kann? oder sollte ich es implementieren müssen?Wenn Sie Ihre Worker-Threads zu Daemon-Threads machen, sterben diese ab, wenn alle Nicht-Daemon-Threads (z. B. der Haupt-Thread) beendet wurden.
http://docs.python.org/library/threading.html#threading.Thread.daemon
quelle
isDaemon()
ist False, setzen Sie ihn auf True bysetDaemon(True)
.isDaemon()
undsetDaemon()
sind alte Getter / Setter (wie im oben verlinkten Dokument beschrieben), verwenden Sie einfachdaemon=True
inthreading.Thread()
Versuchen Sie, den Sub-Thread als Daemon-Thread zu aktivieren.
Zum Beispiel:
Empfohlen:
from threading import Thread t = Thread(target=<your-method>) t.daemon = True # This thread dies when main thread (only non-daemon thread) exits. t.start()
In der Reihe:
t = Thread(target=<your-method>, daemon=True).start()
Alte API:
t.setDaemon(True) t.start()
Wenn Ihr Haupt-Thread beendet wird ("dh wenn ich Ctrl+ drücke C"), werden auch andere Threads durch die obigen Anweisungen beendet.
quelle
Verwenden Sie das atexit- Modul der Python-Standardbibliothek, um "Beendigungs" -Funktionen zu registrieren, die (im Hauptthread) bei einer vernünftig "sauberen" Beendigung des Hauptthreads aufgerufen werden, einschließlich einer nicht erfassten Ausnahme wie z
KeyboardInterrupt
. Solche Beendigungsfunktionen können (obwohl unvermeidlich im Hauptthread!) Jedestop
Funktion aufrufen , die Sie benötigen. Zusammen mit der Möglichkeit, einen Thread alsdaemon
festzulegen, erhalten Sie die Tools, um die von Ihnen benötigten Systemfunktionen richtig zu gestalten.quelle
atexit.register()
Aufrufe in Python-Modulen verschoben werden und Ihre Beendigungsprozedur nach der ersten ausgeführt wirdmultiprocessing
. Ich habe in diesem Problem mitQueue
unddaemon
Threads ausgeführt: "EOF-Fehler" beim Beenden des Programms unter Verwendung von Multiprocessing Queue und Thread .atexit
Handler nicht aufgerufen, wenn Nicht-Daemon-Threads aktiv sind und der Haupt-Thread beendet wird. Siehe Skript beim Beenden hängen bleiben, wenn Sie atexit zum Beenden von Threads verwenden .Wenn Sie einen Thread wie diesen erzeugen -
myThread = Thread(target = function)
- und dann tun Sie esmyThread.start(); myThread.join()
. Wenn STRG-C initiiert wird, wird der Hauptthread nicht beendet, da er auf diesen blockierendenmyThread.join()
Aufruf wartet . Um dies zu beheben, geben Sie einfach eine Zeitüberschreitung für den Aufruf von .join () ein. Das Timeout kann so lange dauern, wie Sie möchten. Wenn Sie möchten, dass es unbegrenzt wartet, geben Sie einfach eine sehr lange Zeitüberschreitung ein, z. B. 99999. Es empfiehlt sich auchmyThread.daemon = True
, alle Threads zu beenden, wenn der Hauptthread (kein Daemon) beendet wird.quelle
myThread.daemon = True
ist eine wunderbare Lösung für dieses Problem..daemon=True
ist keine feste Lösung. Überprüfen Sie diesen Thread für eine Erklärung: stackoverflow.com/a/20598791/5562492Daemon-Threads werden unanständig beendet, sodass keine Finalizer-Anweisungen ausgeführt werden. Eine mögliche Lösung besteht darin, zu überprüfen, ob der Hauptthread anstelle der Endlosschleife aktiv ist.
ZB für Python 3:
while threading.main_thread().isAlive(): do.you.subthread.thing() gracefully.close.the.thread()
Siehe Überprüfen, ob der Haupt-Thread von einem anderen Thread noch aktiv ist .
quelle