Python如何停止continuous_threading的PeriodicThread?调用stop()无效怎么办
问题原因分析
- 你的代码核心问题是每次触发
scan()函数时,都会重新实例化一个全新的PeriodicThread对象赋值给局部变量t1,当你在else分支调用t1.stop()时,停止的是这个刚创建、还没启动的新线程,对之前已经在后台运行的旧线程完全没有影响,所以看起来stop方法不生效。 - 同时Tkinter GUI开发中把线程对象设为局部变量,函数执行完局部变量会被回收,也会导致后续无法操作已经启动的线程。
修复方案
将线程对象改为全局变量/类属性,保证每次操作的都是同一个已经启动的线程实例,修改后的参考代码如下:
import continuous_threading import tkinter as tk # 把线程对象设为全局变量,初始值为None t1 = None def readserial(): # 这里保留你原来的串口读取逻辑 pass def scan(): global t1 print("in scan") btn1_state = var1.get() print("Scan: %d"%btn1_state) if btn1_state == 1: # 仅当线程不存在/未运行时才创建启动,避免重复创建线程 if t1 is None or not t1.is_alive(): t1 = continuous_threading.PeriodicThread(0.5, readserial) t1.start() else: print("entered else ") # 仅当线程存在且处于运行状态时才调用停止方法 if t1 is not None and t1.is_alive(): t1.stop() t1.join() # 可选配置:等待线程完全退出,避免进程残留 t1 = None # 重置变量,方便后续重新启动线程 # 下方保留你原来的Tkinter初始化逻辑即可 root = tk.Tk() var1 = tk.IntVar() chk1 = tk.Checkbutton(root, text='开启串口扫描', variable=var1, command=scan) chk1.pack() root.mainloop()
额外注意事项
- 调用
stop()后线程不会立刻终止,会等待当前正在执行的readserial函数执行完成后才会停止。如果你的readserial里有阻塞操作(比如串口读超时设置很长),可以把阻塞超时设短一点,加快停止响应速度。 - Tkinter不是线程安全的,不要在串口读取线程里直接操作Tkinter控件,跨线程更新UI需要用
root.after()方法调度到主线程执行。
内容的提问来源于stack exchange,提问作者ABHIJEET GAONKAR
相关产品推荐
相关产品推荐

