Dies könnte eine dumme Frage sein, aber ich teste einige meiner Annahmen über Python und bin verwirrt darüber, warum das folgende Codefragment beim Aufruf im Thread nicht beendet wird, sondern beim Aufruf im Hauptthread beendet wird.
import sys, time
from threading import Thread
def testexit():
time.sleep(5)
sys.exit()
print "post thread exit"
t = Thread(target = testexit)
t.start()
t.join()
print "pre main exit, post thread exit"
sys.exit()
print "post main exit"
In den Dokumenten für sys.exit () wird angegeben, dass der Aufruf von Python beendet werden soll. Ich kann der Ausgabe dieses Programms entnehmen, dass "Post-Thread-Exit" nie gedruckt wird, aber der Haupt-Thread läuft einfach weiter, selbst nachdem der Thread Exit aufgerufen hat.
Wird für jeden Thread eine separate Instanz des Interpreters erstellt, und der Aufruf von exit () beendet nur diese separate Instanz? Wenn ja, wie verwaltet die Threading-Implementierung den Zugriff auf freigegebene Ressourcen? Was wäre, wenn ich das Programm aus dem Thread beenden wollte (nicht, dass ich es wirklich möchte, aber nur damit ich es verstehe)?
quelle
os._exit
Verwendung innerhalb von Flüchen die Konsole damit nicht auf einen normalen Zustand zurückgesetzt wird. Sie müssenreset
in der Unix-Shell ausführen , um dies zu beheben.Zumindest unter Linux können Sie Folgendes tun:
Dies sendet a
SIGINT
an den Haupt-Thread, der a auslöstKeyboardInterrupt
. Damit haben Sie eine ordentliche Bereinigung. Sie können das Signal sogar verarbeiten, wenn Sie dies benötigen.Übrigens: Unter Windows können Sie nur ein
SIGTERM
Signal senden , das von Python nicht abgefangen werden kann. In diesem Fall können Sie einfachos._exit
mit dem gleichen Effekt verwenden.quelle
Ist die Tatsache, dass "Pre-Main-Exit, Post-Thread-Exit" gedruckt wird, was Sie stört?
Im Gegensatz zu einigen anderen Sprachen (wie Java), in denen das Analoge zu
sys.exit
(System.exit
im Fall von Java) dazu führt, dass die VM / der Prozess / der Interpreter sofort gestoppt wird, löst Pythonsys.exit
nur eine Ausnahme aus: insbesondere eine SystemExit-Ausnahme.Hier sind die Dokumente für
sys.exit
(nurprint sys.exit.__doc__
):Dies hat einige Konsequenzen:
__del__
) werden möglicherweise aufgerufen, wenn die Stapelrahmen, die auf diese Objekte verweisen, abgewickelt werdenSystemExit
Ausnahme abfangenDer letzte ist möglicherweise der überraschendste und ein weiterer Grund, warum Sie fast nie eine uneingeschränkte
except
Aussage in Ihrem Python-Code haben sollten.quelle
Meine bevorzugte Methode ist das Erlang-ish-Message-Passing. Leicht vereinfacht mache ich das so:
quelle
Queue
hier. Nur ein einfacher reicht ausbool
. Der klassische Name für diese Variable lautetis_active
und der anfängliche Standardwert lautetTrue
.bool
(oder einer anderen atomaren Operation) für dieses spezielle Problem perfekt geeignet. Der Grund , warum ich mit gehenQueue
s ist , dass , wenn sie mit Gewindemitteln arbeiten Ich neige dazu , verschiedene Signale , um am Ende benötigen (flush
,reconnect
,exit
, etc ...) fast sofort.