2009-06-01 11 views
7

Ho bisogno di passare eccezioni attraverso un limite di thread.Come passare un'eccezione tra i thread in python

Sto usando python incorporato in un'applicazione non thread-safe che ha una chiamata thread-safe, post_event (callable), che chiama callable dal thread principale.

Sto eseguendo un pygtk gui in un thread separato, quindi quando si fa clic su un pulsante, inserisco un evento con post_event e attendo che finisca prima di continuare. Ma ho bisogno che il chiamante sappia se il destinatario ha lanciato un'eccezione e lo ha sollevato in tal caso. Non sono troppo preoccupato per il traceback, solo per l'eccezione stessa.

Il mio codice è più o meno:

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 

Qualsiasi aiuto apprezzato, grazie.

risposta

12

# cosa devo fare qui? Come immagazzino l'eccezione?

Usa sys.exc_info()[:2], vedere this wiki

modo migliore per comunicare tra i thread è Queue. Avere il thread principale istanziare un'istanza Queue.Queue e passarlo a sottotitoli; quando una sottotrama ha qualcosa da comunicare al master utilizza .put su quella coda (ad esempio una tupla con ID di thread, tipo di eccezione, valore di eccezione - o altre informazioni utili, non necessariamente correlate alle eccezioni, assicurati solo del primo elemento di una tupla identifica il tipo di informazioni ;-). Il master può .get restituire tali unità di informazione quando lo desidera, con varie opzioni per la sincronizzazione e così via.

+0

Esattamente quello che stavo cercando, grazie. Ordinariamente userei le code, ecc., Ma sto 're-inventando la ruota' perché solo una cosa dovrebbe essere in esecuzione in qualsiasi momento nel mio script, e voglio che roba che gira sul thread della app per finire e dare un risultato prima di intraprendere ulteriori azioni nel thread gtk. Fondamentalmente sto provando a simulare il single threading con due thread. È fastidioso ma sembra funzionare bene. – DaedalusFall

Problemi correlati