Python线程终止方法
Python线程终止有很多思路,本文介绍使用事件终止、状态终止和异常终止3种思路。事件终止和状态终止必须等待耗时任务结束后才能结束,异常终止可以立刻终止。
1 事件终止
借助线程种的事件,终止线程。
import ctypes
import inspect
import threading
import time
class StopThread(threading.Thread):
def __init__(self):
super().__init__()
# 设置停止事件
self.stop_event = threading.Event()
def run(self):
# 清空事件
self.stop_event.clear()
i = 0
# 判断是否终止
while not self.stop_event.is_set():
i = i + 1
print("Start=" + str(i))
time.sleep(1)
print("Task=" + str(i))
time.sleep(1)
print("end=" + str(i))
print("====")
# 终止线程
def stop(self):
self.stop_event.set()
def stop_thread_now(thread_id, except_type):
"""
通过C语言的库抛出异常
:param thread_id: 线程id
:param except_type: 异常抛出类型
:return:
"""
# 在子线程内部抛出一个异常结束线程
thread_id = ctypes.c_long(thread_id)
if not inspect.isclass(except_type):
except_type = type(except_type)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, ctypes.py_object(except_type))
if res == 0:
raise ValueError("线程id违法")
elif res != 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None)
raise SystemError("异常抛出失败")
if __name__ == '__main__':
# 创建线程
stop_thread = StopThread()
stop_thread.start()
time.sleep(3)
# 停止线程,需要等待循环完成,不能立刻中断
stop_thread.stop()
# 停止线程,立刻终止
# stop_thread_now(stop_thread.ident, SystemExit)
2 状态终止
状态终止的思路和事件终止思路相同。
import threading
import time
class StopThread(threading.Thread):
def __init__(self):
super().__init__()
self.status = True
def run(self):
i = 0
while self.status:
i = i + 1
print("Start=" + str(i))
time.sleep(1)
print("Task=" + str(i))
time.sleep(1)
print("end=" + str(i))
print("====")
# 终止线程
def stop(self):
self.status = False
if __name__ == '__main__':
# 创建线程
stop_thread = StopThread()
stop_thread.start()
# 停止线程,需要等待循环完成,不能立刻中断
time.sleep(3)
stop_thread.stop()
3 异常终止
import ctypes
import inspect
import threading
import time
def run_task(param_inner, update_task_inner):
"""
运行任务
:param param_inner: 输入的参数
:param update_task_inner: 输入的方法,停止任务的回调函数
:return:
"""
print(param_inner)
i = 0
while True:
i = i + 1
print("Start=" + str(i))
time.sleep(1)
print("Task=" + str(i))
time.sleep(1)
print("end=" + str(i))
# 回调方法,
update_task_inner("finish=" + str(i))
print("====")
def stop_thread_now(thread_id, except_type):
"""
通过C语言的库抛出异常
:param thread_id: 线程id
:param except_type: 异常抛出类型
:return:
"""
# 在子线程内部抛出一个异常结束线程
thread_id = ctypes.c_long(thread_id)
if not inspect.isclass(except_type):
except_type = type(except_type)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, ctypes.py_object(except_type))
if res == 0:
raise ValueError("线程id违法")
elif res != 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None)
raise SystemError("异常抛出失败")
def update_task(msg):
print(msg)
pass
if __name__ == '__main__':
param = "test"
task_thread = threading.Thread(
# 运行的线程
target=run_task,
# 输入参数
args=(param, update_task)
)
task_thread.start()
time.sleep(4)
# 立刻中断线程
stop_thread_now(task_thread.ident, SystemExit)