AsyncTasks
2024-11|Packages
A Python library for managing asynchronous tasks
查看源码幕后花絮
异步任务的取消和超时,是一种常见的业务需求。
但在 Python 中,原生的 Thread 并不支持中途终止和超时的能力。假设我们在主线程开启了多个长耗时的异步任务 Thread,想要在某个时刻立即终止所有任务,这是做不到的。
为了实现这一目的,通常的做法是通过设置退出标志的方式,告知子线程终止。比如在循环开始/结束时刻,通过读取最新标识,判断是否需要退出。如果我们要想在循环内部打断运行,则必须按照任务的颗粒度,手动埋点判断是否需要退出。
显然上面的做法十分繁琐。
要是我们能够实现无侵入的在任意时刻打断 Thread 运行就好了。
核心实现
要做到在任意位置打断 Python 代码的运行,其实原理非常简单:
抛出异常。要是一个不够,那就一直抛...
import ctypes
import threading
class ThreadStoppedException(BaseException):
def __str__(self):
return self.__class__.__name__
class StoppableThread(threading.Thread):
def stop(self, max_exceptions=10):
c_tid = ctypes.c_ulong(self.ident)
c_exception = ctypes.py_object(ThreadStoppedException)
try:
count = 0
while self.is_alive() and count < max_exceptions:
ctypes.pythonapi.PyThreadState_SetAsyncExc(c_tid, c_exception)
count += 1
except BaseException:
pass
return not self.is_alive()
就是这么酸爽、朴实无华且枯燥,哈哈