2009-06-01 6 views
7

Je dois passer des exceptions à travers une limite de thread. J'utilise python intégré dans une application non thread thread qui a un appel thread sûr, post_event (appelable), qui appelle appelable de son thread principal. Je cours un pygtk gui dans un fil séparé, ainsi quand un bouton est cliqué je publie un événement avec post_event, et attends qu'il finisse avant de continuer. Mais j'ai besoin de l'appelant pour savoir si l'appelé a jeté une exception, et l'augmenter si c'est le cas. Je ne m'inquiète pas trop de la traceback, juste de l'exception elle-même.Comment passer une exception entre threads en python

Mon code est à peu près:

class Callback(): 
    def __init__(self,func,*args): 
     self.func=func 
     self.args=args 
     self.event=threading.Event() 
     self.result=None 
     self.exception=None 
    def __call__(self): 
     gtk.gdk.threads_enter() 
     try: 
      self.result=self.func(*self.args) 
     except: 
      #what do I do here? How do I store the exception? 
      pass 
     finally: 
      gtk.gdk.threads_leave() 
      self.event.set() 
    def post(self): 
     post_event(self) 
     gtk.gdk.threads_leave() 
     self.event.wait() 
     gtk.gdk.threads_enter() 
     if self.exception: 
      raise self.exception 
     return self.result 

Toute aide appréciée, merci.

Répondre

12

# Que fais-je ici? Comment puis-je stocker l'exception?

utilisation sys.exc_info()[:2], voir this wiki

La meilleure façon de communiquer entre les threads est Queue. Demandez au thread principal d'instancier une instance Queue.Queue et de la passer aux sous-threads; quand un sous-thread a quelque chose à communiquer au maître, il utilise .put sur cette file (par exemple un tuple avec l'ID du thread, le type d'exception, la valeur d'exception - ou d'autres informations utiles, pas forcément liées aux exceptions d'un tuple identifie le genre d'info ;-). Le maître peut .get retourner ces info-unités quand il veut, avec différents choix pour la synchronisation et ainsi de suite.

+0

Exactement ce que j'étais après, merci. D'habitude j'utiliserais des files d'attente, etc., mais je suis en train de 'réinventer la roue' parce qu'une seule chose devrait être exécutée à la fois dans mon script, et je veux que les choses qui tournent sur le fil de l'application finissent moi un résultat avant de prendre d'autres mesures dans le fil gtk. Essentiellement, j'essaie de simuler un seul thread avec deux threads. C'est énervant mais ça a l'air de bien marcher. – DaedalusFall

Questions connexes