2009-07-30 12 views
8

Heute lief ich gegen die Tatsache, dass sys.exit() von einem Kind-Thread aufgerufen nicht den Hauptprozess zu töten. Ich wusste das vorher nicht, und das ist okay, aber ich brauchte lange Zeit, um dies zu erkennen. Es hätte viel viel Zeit gespart, wenn sys.exit(msg)msg bis stderr gedruckt hätte. Aber es tat es nicht.Python: Warum ruft `sys.exit (msg)` von einem Thread nicht `msg` an stderr?

Es stellte sich heraus, dass es kein richtiger Fehler in meiner Anwendung war; es rief sys.exit(msg) mit einem bedeutungsvollen Fehler in einer volitionalen Weise an - aber ich konnte es einfach nicht sehen.

In the docs for sys.exit() it is stated:

für einen Anruf von einem Kind-Thread, Dies ist nicht wahr „[...] ein anderes Objekt zu sys.stderr und führt zu einem Beendigungscode 1 wird gedruckt“ wo sys.exit() verhält sich offenbar als thread.exit(): „um die Systemexit Ausnahme auslösen, wenn nicht gefangen, führt dies zu dem Faden leise zu verlassen.“

Ich denke, wenn ein Programmierer sys.exit(msg) eine Fehlermeldung ausgeben möchte, sollte dies nur gedruckt werden - unabhängig von dem Ort, aus dem es aufgerufen wird. Warum nicht? Ich sehe derzeit keinen Grund. Zumindest sollte ein Hinweis in der Dokumentation für sys.exit() sein, dass die Nachricht nicht aus Threads gedruckt wird.

Was denkst du? Warum werden Fehlermeldungen von Threads verborgen? Macht das Sinn?

Mit freundlichen Grüßen,

Jan-Philip Gehrcke

Antwort

6

Ich stimme zu, dass die Python-Dokumente in Bezug auf sys.exit und SystemExit falsch oder vielleicht genauer unvollständig sind, wenn sie von anderen Threads als dem Haupt-Thread aufgerufen/ausgelöst werden; Bitte öffnen Sie ein DOC-Problem im Python-Online-Tracker, damit dies in einer zukünftigen Iteration der Dokumente angesprochen werden kann (wahrscheinlich in naher Zukunft) - doc-Fixes sind einfacher und reibungsloser als Code-Fixes ;-).

Das Mittel ist recht einfach, natürlich - wickeln einfach jede Funktion, die Sie als Ziel eines threading.Thread mit einem Dekorateur verwenden, die einen um ihn herum try/except SystemExit, e: der Fall ist, und führt die „schreiben, um stderr“ zusätzliche Funktionalität Sie benötigen (oder besser, verwenden Sie stattdessen einen logging.error-Aufruf) vor dem Beenden. Aber mit dem doc-Problem, auf das Sie richtig hinweisen, ist es schwierig, darüber nachzudenken, solange und nicht bis einer das Problem gelöst hat und in der Tat einige Zeit im Debuggen verbringen musste, um es festzuhalten, wie Sie es mussten tun (im kollektiven Namen der Core-Python-Entwickler - Entschuldigung!).

+0

Sie gaben mir einen guten Rat, wieder;) Btw: Es ist so toll, dass Sie Ihr Wissen hier teilen. Ich sehe, dass du momentan viel Zeit damit verbringst, diese Plattform mit reinem Experten-Python-Zeug zu füllen!Das braucht die Gemeinschaft, aber das ist keine Selbstverständlichkeit. Ein sehr, sehr großes Dankeschön dafür! Jan-Philip –

+0

@ Jan-Philip, Sie sind herzlich willkommen, und, vielen Dank für die Anerkennung, es ist immer toll zu hören, dass ich Hilfe bin! –

0

Nicht alle Fäden in Python gleich sind. Wenn sys.exit von einem Thread aufgerufen wird, wird das System nicht tatsächlich beendet. Daher ist das Aufrufen von sys.exit() von einem untergeordneten Thread unsinnig, daher ist es sinnvoll, dass es sich nicht wie erwartet verhält.

Diese page spricht mehr über Threading-Objekte und die Unterschiede zwischen Threads und dem speziellen "Haupt" -Thread.