2009-07-30 2 views
8

Oggi mi sono imbattuto nel fatto, che chiamato da un thread secondario non uccida il processo principale. Non lo sapevo prima, e va bene, ma ho avuto bisogno di molto tempo per rendermene conto. Avrebbe risparmiato molto tempo, se sys.exit(msg) avrebbe stampato msg a stderr. Ma non è stato così.Python: Perché `sys.exit (msg)` chiamato da un thread non stampa `msg` in stderr?

Si è scoperto che non era un vero bug nella mia applicazione; si chiamava sys.exit(msg) con un errore significativo in modo volitivo, ma non riuscivo a vederlo.

In the docs for sys.exit() it is stated: "[...] qualsiasi altro oggetto viene stampato sys.stderr e si traduce in un codice di uscita di 1"

Questo è non è vero per una chiamata da un bambino-thread, dove sys.exit() comporta ovviamente come thread.exit(): "Sollevare l'eccezione SystemExit Quando non catturati, ciò farà sì che il filo per uscire silenziosamente."

Penso che quando un programmatore vuole che sys.exit(msg) stampi un messaggio di errore, questo dovrebbe essere stampato - indipendentemente dal luogo da cui viene chiamato. Perchè no? Al momento non vedo alcuna ragione. Almeno ci dovrebbe essere un suggerimento nei documenti per che il messaggio non viene stampato dai thread.

Cosa ne pensi? Perché i messaggi di errore sono nascosti dai thread? Ha senso ciò?

Con i migliori saluti,

Jan-Philip Gehrcke

risposta

6

Sono d'accordo che i documenti Python non sono corretti, o forse più precisamente incompleti, riguardo a sys.exit e SystemExit quando vengono richiamati/generati da thread diversi da quello principale; si prega di aprire un problema doc sul tracker online Python in modo che questo possa essere affrontato in una futura iterazione dei documenti (probabilmente uno prossimo al prossimo: le correzioni dei documenti sono più semplici e agevoli rispetto alle correzioni del codice ;-).

Il rimedio è abbastanza facile, ovviamente - solo avvolgere qualsiasi funzione che si sta utilizzando come bersaglio di un threading.Thread con un decoratore che fa un try/except SystemExit, e: intorno ad esso, ed esegue la "scrittura su stderr" funzionalità extra è necessario (o, forse meglio, usa una chiamata logging.error) prima di terminare. Ma, con il problema del doc che tu correttamente sottolinei, è difficile pensare di farlo a meno che e fino a quando uno non ha incontrato il problema e in effetti ha dovuto trascorrere un po 'di tempo nel debug per metterlo giù, come hai dovuto fare (per conto collettivo degli sviluppatori core python - sorry!).

+0

Mi hai dato un buon consiglio, di nuovo;) Btw: È così bello che condividi le tue conoscenze qui. Vedo che al momento passi gran parte del tuo tempo a riempire questa piattaforma con roba pura di Python esperta!Questo è ciò di cui la comunità ha bisogno ma non è ovvio. Molto molto grande Grazie per questo! Jan-Philip –

+0

@ Jan-Philip, siete i benvenuti e, grazie per i complimenti, è sempre bello sapere che sono di aiuto! –

0

Non tutte le discussioni in pitone sono uguali. Chiamando sys.exit da un thread, in realtà non esce dal sistema. Quindi, chiamare sys.exit() da un thread figlio è privo di senso, quindi ha senso che non si comporti come ci si aspetta.

Questo page parla di threading degli oggetti e delle differenze tra i thread e lo speciale thread "principale".