Created
April 17, 2012 16:02
-
-
Save liuw/2407154 to your computer and use it in GitHub Desktop.
Revisions
-
liuw created this gist
Apr 17, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,49 @@ #!/usr/bin/env python # liuw # Nasty hack to raise exception for other threads import ctypes # Calm down, this has become standard library since 2.5 import threading import time NULL = 0 def ctype_async_raise(thread_obj, exception): found = False target_tid = 0 for tid, tobj in threading._active.items(): if tobj is thread_obj: found = True target_tid = tid break if not found: raise ValueError("Invalid thread object") ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(target_tid, ctypes.py_object(exception)) # ref: http://docs.python.org/c-api/init.html#PyThreadState_SetAsyncExc if ret == 0: raise ValueError("Invalid thread ID") elif ret > 1: # Huh? Why would we notify more than one threads? # Because we punch a hole into C level interpreter. # So it is better to clean up the mess. ctypes.pythonapi.PyThreadState_SetAsyncExc(target_tid, NULL) raise SystemError("PyThreadState_SetAsyncExc failed") print "Successfully set asynchronized exception for", target_tid def f(): try: while True: time.sleep(1) finally: print "Exited" t = threading.Thread(target=f) t.start() print "Thread started" print t.isAlive() time.sleep(5) ctype_async_raise(t, SystemExit) t.join() print t.isAlive()