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)?
Antworten:
Ü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
isDaemon()
ist False, setzen Sie ihn auf True by setDaemon(True)
.
isDaemon()
und setDaemon()
sind alte Getter / Setter (wie im oben verlinkten Dokument beschrieben), verwenden Sie einfach daemon=True
inthreading.Thread()
Versuchen Sie, den Sub-Thread als Daemon-Thread zu aktivieren.
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.
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!) Jede stop
Funktion aufrufen , die Sie benötigen. Zusammen mit der Möglichkeit, einen Thread als daemon
festzulegen, erhalten Sie die Tools, um die von Ihnen benötigten Systemfunktionen richtig zu gestalten.
atexit.register()
Aufrufe in Python-Modulen verschoben werden und Ihre Beendigungsprozedur nach der ersten ausgeführt wird multiprocessing
. Ich habe in diesem Problem mit Queue
und daemon
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 es myThread.start(); myThread.join()
. Wenn STRG-C initiiert wird, wird der Hauptthread nicht beendet, da er auf diesen blockierenden myThread.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 auch myThread.daemon = True
, alle Threads zu beenden, wenn der Hauptthread (kein Daemon) beendet wird.
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/5562492
Daemon-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 .