import ctypes def ctype_async_raise(thread, exception): tid=thread.ident ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(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") def on_abort(parent_thread): print ("abort") ctype_async_raise(parent_thread, KeyboardInterrupt) time.sleep(10.0)