如何在Python中一次性停止所有通过threading创建的线程?
问题分析
你当前的代码只能停止最后一个启动的线程,原因是循环迭代创建线程时,变量t会被反复覆盖为最新创建的线程对象,循环结束后t仅指向最后一个线程,其余已启动的线程的do_run属性始终不会被修改,因此不会触发停止逻辑。
实现方案
要一次性停止所有线程,你只需要把所有启动的线程实例存入一个列表,需要停止时遍历列表统一修改停止标记即可。更规范的实现可以用threading.Event作为全局停止信号,避免单独修改每个线程的属性:
import threading import time # 全局停止信号 stop_event = threading.Event() def doit(arg): while not stop_event.is_set(): print(f"working on {arg}") time.sleep(10) print("Stopping as you wish.") def main(): threads = [] with open('C:\\Users\\Admin\\Desktop\\dump\\domains.txt') as file: for line in file: line_content = line.rstrip() print(line_content) t = threading.Thread(target=doit, args=(line_content, )) t.start() threads.append(t) # 这里可替换为你自己的停止触发逻辑,比如任务完成判定、超时判断等 input("按回车停止所有线程>>>") # 触发停止信号,所有线程都会收到 stop_event.set() # 等待所有线程正常退出 for t in threads: t.join() print("所有线程已停止") if __name__ == "__main__": main()
可选优化
- 如果要沿用你原来的
do_run属性的写法,也可以按如下逻辑修改:
# 沿用原属性标记逻辑的改法 def main(): threads = [] with open('C:\\Users\\Admin\\Desktop\\dump\\domains.txt') as file: for line in file: line_content = line.rstrip() print(line_content) t = threading.Thread(target=doit, args=(line_content, )) t.start() threads.append(t) input("按回车停止所有线程>>>") # 遍历所有线程设置停止标记 for t in threads: t.do_run = False for t in threads: t.join()
- 原代码中
doit函数有10秒的sleep,线程最多会延迟10秒才会响应停止信号,如果需要更快响应,可以把长睡眠拆分为短时间片循环检测:
def doit(arg): t = threading.currentThread() while getattr(t, "do_run", True): print ("working on %s" % arg) # 拆成10次1秒的睡眠,每秒检测一次停止标记 for _ in range(10): if not getattr(t, "do_run", True): break time.sleep(1) print("Stopping as you wish.")
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

