Sollevare le eccezioni non gestite in un thread nel thread principale? [duplicare]
-
13-09-2019 - |
Domanda
Questa domanda ha già una risposta qui:
Ci sono alcune domande simili, ma nessuno forniscono la risposta ho bisogno.
Se creo le discussioni via threading.Thread
, che poi gettano eccezioni che sono non gestita, questi fili vengono terminati. Vorrei mantenere la stampa predefinito fuori i dettagli di eccezione con l'analisi dello stack, ma far cadere l'intero processo pure.
ho considerato che potrebbe essere possibile raggiungere tutte le eccezioni nei fili, e reraise sull'oggetto thread principale, o forse è possibile eseguire manualmente la gestione delle eccezioni di default, e poi alzare un SystemExit
sul thread principale .
Qual è il modo migliore per andare su questo?
Soluzione
ho scritto su Re-generare eccezioni in Python , tra cui qualcosa di molto simile questo come esempio.
Sul thread di lavoro si esegue questa operazione (Python 2.x, vedi sotto per la versione 3.x di Python):
try:
self.result = self.do_something_dangerous()
except Exception, e:
import sys
self.exc_info = sys.exc_info()
e sul thread principale si esegue questa operazione:
if self.exc_info:
raise self.exc_info[1], None, self.exc_info[2]
return self.result
L'eccezione apparirà nel thread principale proprio come se fosse stata sollevata nel thread di lavoro.
Python 3.x:
try:
self.result = self.do_something_dangerous()
except Exception as e:
import sys
self.exc_info = sys.exc_info()
e sul thread principale:
if self.exc_info:
raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result
Altri suggerimenti
L'unica eccezione un thread secondario può aumentare in modo affidabile nel thread principale è KeyboardInterrupt
: il modo in cui il filo secondario fa è chiamando la funzione thread.interrupt_main()
. Non v'è alcun modo per associare informazioni extra (circa il motivo per l'eccezione) con l'oggetto eccezione che viene sollevato - quest'ultimo è sempre e solo un KeyboardInterrupt
pianura. Quindi, è necessario riporre le informazioni via da qualche altra parte, ad esempio, su un'istanza dedicata di Queue.Queue - queste informazioni potrebbe includere i risultati thread secondario può ottenere tramite sys.exc_info()
, e niente altro che trovare utili, naturalmente.
Il thread principale avrà bisogno di recuperare queste informazioni in più (e tener conto che la coda sarà vuota se l'interrupt tastiera è effettivamente dovuto per l'utente che colpisce di controllo-C o simili, così, l'uso get_nowait
ed essere pronti a trattare con un'eccezione Queue.Empty
, per esempio), il formato che tuttavia si desidera, e terminare (se tutte le discussioni secondari sono demone s, l'intero processo termina quando il filo principale termina).
Molto, purtroppo, la risposta accettata non rispondere alla domanda. Si preferisce tubi i dettagli di eccezione in una coda. Si prega di dare un'occhiata a: Prendere eccezione di un thread nel thread chiamante in Python