虽然它很老,
this
对某些人来说可能是个方便的解决方案:
扩展线程模块功能的小模块--
允许一个线程在另一个线程的上下文中引发异常
线程。通过提高
SystemExit
,最终可以杀死python线程。
import threading
import ctypes
def _async_raise(tid, excobj):
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(excobj))
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
raise SystemError("PyThreadState_SetAsyncExc failed")
class Thread(threading.Thread):
def raise_exc(self, excobj):
assert self.isAlive(), "thread must be started"
for tid, tobj in threading._active.items():
if tobj is self:
_async_raise(tid, excobj)
return
# the thread was alive when we entered the loop, but was not found
# in the dict, hence it must have been already terminated. should we raise
# an exception here? silently ignore?
def terminate(self):
# must raise the SystemExit type, instead of a SystemExit() instance
# due to a bug in PyThreadState_SetAsyncExc
self.raise_exc(SystemExit)
因此,它允许一个“线程在另一个线程的上下文中引发异常”,这样,终止的线程就可以在不定期检查中止标志的情况下处理终止。
然而,根据其
original source
,此代码有一些问题。
-
只有在执行python字节码时才会引发异常。如果线程调用本机/内置的阻塞函数,则
只有当执行返回到python时才会引发异常
代码。
-
如果内置函数内部调用pyerr_clear(),也会出现问题,这将有效地取消挂起的异常。
你可以再举一次。
-
只能安全地引发异常类型。异常实例可能导致意外行为,因此受到限制。
-
我要求在内置线程模块中公开这个函数,但是由于cTypes已经成为一个标准库(从2.5开始),所以
功能不太可能是实现不可知的,它可以保留
未暴露的