self.th = threading.Thread(target=self.fun)
用 th.stop() 会报错 'Thread' object has no attribute 'stop',请教threading如何在运行过程中停止
from threading import Thread
import time
import inspect
import ctypes
def _async_raise(tid, exctype):
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid 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, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
thread._is_stopped = True # 修改线程状态
_async_raise(thread.ident, SystemExit)
def task():
for i in range(1, 100):
print(i)
time.sleep(1)
if __name__ == '__main__':
th = Thread(target=task)
th.start() # 开始线程
print(th.is_alive()) # 查看线程运行状态
time.sleep(2)
stop_thread(th) # 终止线程
print(th.is_alive()) # 查看线程运行状态
运行结果:
完全可以实现如下示例代码所示的Thread.stop方法:
import threading
import sys
class StopThread(StopIteration): pass
threading.SystemExit = SystemExit, StopThread
class Thread2(threading.Thread):
def stop(self):
self.__stop = True
def _bootstrap(self):
if threading._trace_hook is not None:
raise ValueError('Cannot run thread with tracing!')
self.__stop = False
sys.settrace(self.__trace)
super()._bootstrap()
def __trace(self, frame, event, arg):
if self.__stop:
raise StopThread()
return self.__trace
class Thread3(threading.Thread):
def _bootstrap(self, stop_thread=False):
def stop():
nonlocal stop_thread
stop_thread = True
self.stop = stop
def tracer(*_):
if stop_thread:
raise StopThread()
return tracer
sys.settrace(tracer)
super()._bootstrap()
################################################################################
import time
def main():
test = Thread2(target=printer)
test.start()
time.sleep(1)
test.stop()
test.join()
def printer():
while True:
print(time.time() % 1)
time.sleep(0.1)
if __name__ == '__main__':
main()
开启线程没有 stop 这个功能, .join() 是等待线程结束,可以在self.fun中 使用os.getpid() 获取到该线程的 pid号, 然后直接杀掉该线程即可