私信  •  关注

wp78de

wp78de 最近创建的主题
wp78de 最近回复了
6 年前
回复了 wp78de 创建的主题 » 强制退出运行python中的线程[duplicate]

虽然它很老, 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开始),所以
    功能不太可能是实现不可知的,它可以保留
    未暴露的