killable thread的python实现

python没有为内置的threading.Thread类提供一个kill接口,可以通过使用CPython API向线程抛出一个SystemExit异常来终止线程。如果线程没有被系统调用阻塞(sleep, recv, accept等),线程将会强制退出。参考连接:https://github.com/munshigroup/kthread.

import ctypes
import inspect

try:
    import thread
except ImportError:
    import _thread as thread
import threading

name = "kthread"

def _async_raise(tid, exctype):
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("Invalid thread ID")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class KThread(threading.Thread):
    def _get_my_tid(self):
        if not self.isAlive():
            raise threading.ThreadError("Thread is not active")
        
        if hasattr(self, "_thread_id"):
            return self._thread_id

        for tid, tobj in threading._active.items():
            if tobj is self:
                self._thread_id = tid
                return tid
        
        raise AssertionError("Could not determine the thread's ID")
    
    def raise_exc(self, exctype):
        _async_raise(self._get_my_tid(), exctype)
    
    def terminate(self):
        """cause the thread to exit silently (unless caught)"""
        # terminate会被系统调用(recv, sleep, accept等)阻塞
        self.raise_exc(SystemExit)

    def kill(self):
        self.terminate()
        
    def exit(self):
        self.terminate()

 

posted @ 2021-01-31 15:40  zcsh  阅读(180)  评论(0编辑  收藏  举报