Question

    

Cette question a déjà une réponse ici:

         

Il y a des questions similaires, mais aucune réponse fournir que je demande.

Si je crée des fils via threading.Thread, qui a ensuite lancer des exceptions qui sont unhandled, ces fils sont terminés. Je souhaite conserver l'impression par défaut sur les détails d'exception avec la trace de la pile, mais descendre aussi bien l'ensemble du processus.

Je l'ai considéré qu'il pourrait être possible d'attraper toutes les exceptions dans les fils et les reraise sur l'objet principal de fil, ou peut-être il est possible d'effectuer manuellement la gestion des exceptions par défaut, puis soulevez un SystemExit sur le thread principal .

Quelle est la meilleure façon d'aller à ce sujet?

Était-ce utile?

La solution

J'ai écrit sur Re-lancer des exceptions en Python , y compris quelque chose de très semblable comme un exemple.

Sur votre thread de travail que vous faites cela (Python 2.x, voir ci-dessous pour la version Python 3.x):

try:
    self.result = self.do_something_dangerous()
except Exception, e:
    import sys
    self.exc_info = sys.exc_info()

et sur votre thread principal vous faites ceci:

if self.exc_info:
    raise self.exc_info[1], None, self.exc_info[2]
return self.result

L'exception apparaît dans le thread principal comme si elle avait été soulevée dans le thread de travail.

Python 3.x:

try:
    self.result = self.do_something_dangerous()
except Exception as e:
    import sys
    self.exc_info = sys.exc_info()

et sur votre thread principal:

if self.exc_info:
    raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result

Autres conseils

La seule exception d'un thread secondaire peut augmenter de manière fiable dans le thread principal est KeyboardInterrupt: la façon dont le fil secondaire, il est fait en appelant la fonction thread.interrupt_main() . Il n'y a pas moyen d'associer informations supplémentaires (la raison de l'exception) avec l'objet d'exception qui est soulevée - celle-ci est toujours juste une KeyboardInterrupt plaine. , Vous avez besoin de cacher cette information quelque part d'autre, par exemple sur une instance dédiée de Queue.Queue - cette information pourrait inclure les résultats du thread secondaire peut obtenir via sys.exc_info(), et tout ce que vous trouverez utile bien sûr.

Le fil conducteur devra récupérer cette information supplémentaire (et prendre en compte le fait que la file d'attente sera vide si l'interruption du clavier est en fait due à l'utilisateur de frapper le contrôle-C ou similaire, donc, l'utilisation get_nowait et être prêt à faire face à une exception Queue.Empty, par exemple), le format comme vous le désirez, et mettre fin à (si tous les threads secondaires sont démon s, l'ensemble du processus se termine lorsque le fil principal se termine).

Très malheureusement, la réponse acceptée ne répond pas à la question. Vous feriez tuyaux plutôt les détails d'exception dans une file d'attente. S'il vous plaît jeter un oeil à: Catch exception d'un thread dans le thread de l'appelant en Python

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top