抛出异常到另一个线程
Throw an exception into another thread
这不是任何涉及捕获一个线程从另一个线程抛出的异常的问题的重复。
我有生成一个线程的代码,它会自行运行。
在将来的某个时候,我希望能够在另一个线程中抛出两个异常之一(即 terminate
和 interrupt
)。
一种方法是共享一个变量并让另一个线程定期检查它是否应该被杀死。我的偏好是没有它检查的约束(一些代码将独立于执行线程的库,并且不会被编写来检查)。
在我的理想解决方案中,您最终可能会遇到这样一种情况,在调试时,您可能会发现 auto i = 1 + 1
抛出异常,因为另一个线程告诉您的线程抛出异常,而这正是您 [=25] =]刚好当时开着。
我有办法做到这一点吗?
我认为线程 A 中的异常被线程 B 捕获在概念上没有意义,因为异常的核心概念是展开堆栈,而线程 A 的堆栈与线程 B 的不同堆叠.
你可以做的是在线程 A 中抛出异常,让线程 A 中的异常处理程序捕获异常并通过以某种方式通知线程 B 相关细节来处理它,当线程 B 收到通知时可以响应通过抛出它自己的异常,类似于最初在线程 A 中抛出的异常。
至于如何实现该通知和数据传输,您可以使用任何常用的跨线程 notification/communications 机制(共享原子变量和轮询、套接字对、管道、互斥锁保护的 FIFO 消息队列、等)。
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.
我认为这被称为异步异常,我认为标准 C++ 不支持它。 Microsoft 有他们的 structured exception handling (SEH) 可以做到这一点,但这是一个 proprietary/non-standard 功能。
是的,可以将异常引发到另一个线程中。
我假设您知道在正常程序中不应这样做的所有充分理由。但是,作为测试套件、调试工具或与 python 内部相关的程序的一部分,这可能会有所帮助。
这是解除的,大致来自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")
这不是任何涉及捕获一个线程从另一个线程抛出的异常的问题的重复。
我有生成一个线程的代码,它会自行运行。
在将来的某个时候,我希望能够在另一个线程中抛出两个异常之一(即 terminate
和 interrupt
)。
一种方法是共享一个变量并让另一个线程定期检查它是否应该被杀死。我的偏好是没有它检查的约束(一些代码将独立于执行线程的库,并且不会被编写来检查)。
在我的理想解决方案中,您最终可能会遇到这样一种情况,在调试时,您可能会发现 auto i = 1 + 1
抛出异常,因为另一个线程告诉您的线程抛出异常,而这正是您 [=25] =]刚好当时开着。
我有办法做到这一点吗?
我认为线程 A 中的异常被线程 B 捕获在概念上没有意义,因为异常的核心概念是展开堆栈,而线程 A 的堆栈与线程 B 的不同堆叠.
你可以做的是在线程 A 中抛出异常,让线程 A 中的异常处理程序捕获异常并通过以某种方式通知线程 B 相关细节来处理它,当线程 B 收到通知时可以响应通过抛出它自己的异常,类似于最初在线程 A 中抛出的异常。
至于如何实现该通知和数据传输,您可以使用任何常用的跨线程 notification/communications 机制(共享原子变量和轮询、套接字对、管道、互斥锁保护的 FIFO 消息队列、等)。
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.
我认为这被称为异步异常,我认为标准 C++ 不支持它。 Microsoft 有他们的 structured exception handling (SEH) 可以做到这一点,但这是一个 proprietary/non-standard 功能。
是的,可以将异常引发到另一个线程中。
我假设您知道在正常程序中不应这样做的所有充分理由。但是,作为测试套件、调试工具或与 python 内部相关的程序的一部分,这可能会有所帮助。
这是解除的,大致来自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")