Reputation: 8575
I need to pass exceptions across a thread boundary.
I'm using python embedded in a non thread safe app which has one thread safe call, post_event(callable), which calls callable from its main thread.
I am running a pygtk gui in a seperate thread, so when a button is clicked I post an event with post_event, and wait for it to finish before continuing. But I need the caller to know if the callee threw an exception, and raise it if so. I'm not too worried about the traceback, just the exception itself.
My code is roughly:
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
Any help appreciated, thanks.
Upvotes: 7
Views: 6750
Reputation: 881645
#what do I do here? How do I store the exception?
Use sys.exc_info()[:2]
, see this wiki
Best way to communicate among threads is Queue. Have the main thread instantiate a Queue.Queue
instance and pass it to subthreads; when a subthread has something to communicate back to the master it uses .put
on that queue (e.g. a tuple with thread id, exception type, exception value -- or, other useful info, not necessarily exception-related, just make sure the first item of a tuple identifies the kind of info;-). The master can .get
those info-units back when it wants, with various choices for synchronization and so on.
Upvotes: 13