【发布时间】:2022-11-29 16:10:35
【问题描述】:
我想通过设置一个事件以某种方式从我的 GUI 应用程序中杀死一个正在运行的线程,但是我不能在我的线程中使用 for 循环所以我需要一些其他的解决方案来检查事件
我有以下情况。 在 tkinter gui 中,当我单击一个按钮时,我启动一个线程并设置一个全局变量。
self.thread = StoppableThread(caller=self)
self.thread.start()
is_running = 1
当我下次单击按钮时,我检查全局变量状态,如果它已经设置,我发送一个停止请求:
if is_running:
is_running = 0
self.thread.stop()
这是我的线程类:
import threading
from time import sleep
class StoppableThread(threading.Thread):
def __init__(self, caller=None):
super(StoppableThread, self).__init__()
self._stop_event = threading.Event()
self.caller = caller
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
def run(self) -> None:
while True:
# check for stop
if self.stopped():
break
for i in range(10):
sleep(1)
print('Test')
print('Worker done')
break
如果我将 while 更改为 for 循环,则一切正常,但因为在我的业务逻辑中的这一点上,我没有任何可循环的东西,因为我需要以某种方式检查 self.stopped() 的不同状态。有没有办法在 while 循环中检查它?
或者我怎样才能做到这一点?我尝试使用进程而不是线程,但由于错误“进程无法腌制 tkinter”而无法正常工作。
感谢您的任何帮助
【问题讨论】:
-
您只需在开始时检查一次
stopped标志,因为在第一个循环之后您是break。只需删除for语句(但保留内容),并删除print('Worker done')和break。 -
由于 while 循环末尾的
break,while 循环仅运行一次迭代。此外,最好发布按您所说的那样工作的 for 循环“如果我将 while 更改为 for 循环,一切正常”. -
如果您至少描述您在此线程中正在做什么,以指出有效的解决方案,这将有所帮助。当您的问题已写好时,您需要做的就是删除
break语句并将print('Worker done')从您的 while 循环中移出封闭空间。由于您解析了一个caller并且您包含的错误指出它是您正在解析的一个小部件,因此即使进行了这些更改,您的体系结构仍然很可能会中断。 -
哦,是的,删除中断是个好点,对不起,但仍然没有停止。
-
@Thingamabobs 我不想在这里复制整个线程处理。但这里有一个描述。启动线程后,我从数据库中读取了一些数据并将它们传递给另一个处理类。在这个类中,我做很长时间的处理任务,向 API 发送请求等等。有些情况我想从这里突破并且不要等到例如所有 20 个请求(每小时 1 个请求)完成。
标签: python python-3.x multithreading tkinter