This is not a duplicate of any question involving catching an exception thrown in one thread from another.
I have code which spawns a thread, and it goes off and does its own thing.
At some point in the future, I'd like to be able to throw one of two exceptions in the other thread (i.e. terminate
and interrupt
).
One way to do this is to have a variable shared and have the other thread periodically check if it should be killed. My preference is to not have the constraint that it checks (some of the code will be independent of the library doing the threading and won't have been written to check).
In my ideal solution, you may end up in a situation where, debugging, you might find that auto i = 1 + 1
throws an exception because another thread told your thread to throw and that's the line you just happened to be on at the time.
Is there a way I can do this?
Yes, it's possible to raise an exception into another thread.
I'm going to assume you know all the good reasons why this should not be done in a normal program. But as a part of, say, a test suite, a debug tool, or a program that is otherwise concerned with python internals, this might be helpful.
This is lifted, roughly from https://gist.github.com/liuw/2407154
import ctypes
def ctype_async_raise(target_tid, exception):
ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(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")