Go to the documentation of this file.00001 def _async_raise(tid, exctype):
00002 '''Raises an exception in the threads with id tid'''
00003 if not inspect.isclass(exctype):
00004 raise TypeError("Only types can be raised (not instances)")
00005 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
00006 ctypes.py_object(exctype))
00007 if res == 0:
00008 raise ValueError("invalid thread id")
00009 elif res != 1:
00010
00011
00012 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
00013 raise SystemError("PyThreadState_SetAsyncExc failed")
00014
00015 class ThreadWithExc(threading.Thread):
00016 '''A thread class that supports raising exception in the thread from
00017 another thread.
00018 '''
00019 def _get_my_tid(self):
00020 """determines this (self's) thread id
00021
00022 CAREFUL : this function is executed in the context of the caller
00023 thread, to get the identity of the thread represented by this
00024 instance.
00025 """
00026 if not self.isAlive():
00027 raise threading.ThreadError("the thread is not active")
00028
00029
00030 if hasattr(self, "_thread_id"):
00031 return self._thread_id
00032
00033
00034 for tid, tobj in threading._active.items():
00035 if tobj is self:
00036 self._thread_id = tid
00037 return tid
00038
00039
00040
00041 raise AssertionError("could not determine the thread's id")
00042
00043 def raiseExc(self, exctype):
00044 """Raises the given exception type in the context of this thread.
00045
00046 If the thread is busy in a system call (time.sleep(),
00047 socket.accept(), ...), the exception is simply ignored.
00048
00049 If you are sure that your exception should terminate the thread,
00050 one way to ensure that it works is:
00051
00052 t = ThreadWithExc( ... )
00053 ...
00054 t.raiseExc( SomeException )
00055 while t.isAlive():
00056 time.sleep( 0.1 )
00057 t.raiseExc( SomeException )
00058
00059 If the exception is to be caught by the thread, you need a way to
00060 check that your thread has caught it.
00061
00062 CAREFUL : this function is executed in the context of the
00063 caller thread, to raise an excpetion in the context of the
00064 thread represented by this instance.
00065 """
00066 _async_raise( self._get_my_tid(), exctype )