Domanda

Oggi mi sono imbattuto nel fatto che sys.exit () chiamato da un thread figlio non uccide il processo principale. Non lo sapevo prima, e va bene, ma avevo bisogno di molto tempo per realizzarlo. Avrebbe risparmiato molto tempo , se sys.exit (msg) avrebbe stampato msg su stderr . Ma non è stato.

Si è scoperto che non era un vero bug nella mia applicazione; ha chiamato sys.exit (msg) con un errore significativo in modo volontario - ma non riuscivo proprio a vederlo.

Nei documenti per sys.exit () si afferma : " [...] qualsiasi altro oggetto viene stampato su sys.stderr e genera un codice di uscita di 1 "

Questo è non vero per una chiamata da un thread figlio, dove sys.exit () si comporta ovviamente come thread.exit () : " Solleva l'eccezione SystemExit. Se non viene catturato, ciò causerà l'uscita del thread silenziosamente"

Penso che quando un programmatore desidera che sys.exit (msg) stampi un messaggio di errore, questo dovrebbe essere stampato, indipendentemente dal luogo in cui viene chiamato. Perchè no? Al momento non vedo alcun motivo. Almeno dovrebbe esserci un suggerimento nei documenti per sys.exit () che il messaggio non viene stampato dai thread.

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

Cordiali saluti,

Jan-Philip Gehrcke

È stato utile?

Soluzione

Sono d'accordo che i documenti di Python sono errati, o forse più precisamente incompleti, riguardo a sys.exit e SystemExit quando chiamati / generati da thread diversi da quello principale; si prega di aprire un problema relativo ai documenti sul tracker online di Python in modo che possa essere risolto in una futura iterazione dei documenti (probabilmente un prossimo futuro - le correzioni dei documenti sono più facili e fluide rispetto alle correzioni del codice ;-).

Il rimedio è abbastanza semplice, ovviamente: basta avvolgere qualsiasi funzione che stai usando come obiettivo di un threading. Filtra con un decoratore che esegue un prova / tranne SystemExit, e: attorno ad esso, ed esegue la "scrittura su stderr" funzionalità extra richieste (o, forse meglio, utilizza invece una chiamata logging.error) prima di terminare. Ma, con la questione doc che hai correttamente sottolineato, è difficile pensare di farlo a meno che e fino a quando uno non ha riscontrato il problema e in effetti ha dovuto dedicare un po 'di tempo al debug per fissarlo, come hai dovuto do (per conto degli sviluppatori core di Python - scusate!).

Altri suggerimenti

Non tutti i thread in Python sono uguali. Chiamare sys.exit da un thread, in realtà non esce dal sistema. Pertanto, chiamare sys.exit () da un thread figlio non ha senso, quindi ha senso che non si comporti come previsto.

Questa pagina parla di più sugli oggetti thread e le differenze tra thread e speciale "principale" thread.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top