如何在 python 脚本退出时终止线程(如果需要)?
How do I kill my thread on python script exit(If I need to)?
我正在开发一个每秒从 API 中获取数据的程序。所以我有一个名为 tick 的函数,它基本上是来自 API 的 returns 数据。为了能够在等待响应的时候每秒不卡顿地使用GUI,我把它放在一个线程上,像这样:
def every(delay, task):
next_time = time.time() + delay
while True:
time.sleep(max(0, next_time - time.time()))
try:
task()
except Exception:
traceback.print_exc()
# in production code you might want to have this instead of course:
# logger.exception("Problem while executing repetitive task.")
# skip tasks if we are behind schedule:
next_time += (time.time() - next_time) // delay * delay + delay
...
...
threading.Thread(target=lambda: every(1, tick)).start()
window.mainloop()
当我关闭 GUI window 时,python 控制台变得像这样疯狂:
Traceback (most recent call last): File
"D:/PycharmProjects/test/test.py", line 22, in every
task() File "D:/PycharmProjects/test/test.py", line 66, in tick
insert_text(unn1, unn_text) File "D:/PycharmProjects/test/test.py", line 47, in insert_text
entry.delete(0, END) File "D:\Python37\lib\tkinter__init__.py", line 2676, in delete
self.tk.call(self._w, 'delete', first, last) RuntimeError: main thread is not in main loop
我很清楚线程没有终止。但是我是 python 和线程的新手,所以我不知道这个线程是否需要从代码中关闭,或者当我实际上是 运行 编译程序时它会自动关闭它我关闭程序 window。那么,我需要从内部关闭它吗?如果是这样,我该如何正确操作?
您可以使用全局变量(即 running
)来控制 while
循环。
之后你也可以使用thread.join()
等待线程结束。
def every(delay, task):
global running
next_time = time.time() + delay
while running:
...
...
#---------------------------------------------
running = True
thread = threading.Thread(target=lambda: every(1, tick))
thread.start()
window.mainloop()
running = False # it will end `while` loop
thread.join() # it will wait for end of thread
如果 task
时间不长,那么您可以使用 after()
而不是线程和 while
循环。类似于
def every(delay, task):
start = time.time()
try:
task()
except Exception:
traceback.print_exc()
end = time.time()
diff = end - start
after_time = max(0, delay - diff)
if running:
window.after(after_time, every, (1000, task)) # 1000ms=1s
#---------------------------------------------
running = True
window.every(1000, tick) # 1000ms=1s
window.mainloop()
running = False # it will end `while` loop
我正在开发一个每秒从 API 中获取数据的程序。所以我有一个名为 tick 的函数,它基本上是来自 API 的 returns 数据。为了能够在等待响应的时候每秒不卡顿地使用GUI,我把它放在一个线程上,像这样:
def every(delay, task):
next_time = time.time() + delay
while True:
time.sleep(max(0, next_time - time.time()))
try:
task()
except Exception:
traceback.print_exc()
# in production code you might want to have this instead of course:
# logger.exception("Problem while executing repetitive task.")
# skip tasks if we are behind schedule:
next_time += (time.time() - next_time) // delay * delay + delay
...
...
threading.Thread(target=lambda: every(1, tick)).start()
window.mainloop()
当我关闭 GUI window 时,python 控制台变得像这样疯狂:
Traceback (most recent call last): File "D:/PycharmProjects/test/test.py", line 22, in every task() File "D:/PycharmProjects/test/test.py", line 66, in tick insert_text(unn1, unn_text) File "D:/PycharmProjects/test/test.py", line 47, in insert_text entry.delete(0, END) File "D:\Python37\lib\tkinter__init__.py", line 2676, in delete self.tk.call(self._w, 'delete', first, last) RuntimeError: main thread is not in main loop
我很清楚线程没有终止。但是我是 python 和线程的新手,所以我不知道这个线程是否需要从代码中关闭,或者当我实际上是 运行 编译程序时它会自动关闭它我关闭程序 window。那么,我需要从内部关闭它吗?如果是这样,我该如何正确操作?
您可以使用全局变量(即 running
)来控制 while
循环。
之后你也可以使用thread.join()
等待线程结束。
def every(delay, task):
global running
next_time = time.time() + delay
while running:
...
...
#---------------------------------------------
running = True
thread = threading.Thread(target=lambda: every(1, tick))
thread.start()
window.mainloop()
running = False # it will end `while` loop
thread.join() # it will wait for end of thread
如果 task
时间不长,那么您可以使用 after()
而不是线程和 while
循环。类似于
def every(delay, task):
start = time.time()
try:
task()
except Exception:
traceback.print_exc()
end = time.time()
diff = end - start
after_time = max(0, delay - diff)
if running:
window.after(after_time, every, (1000, task)) # 1000ms=1s
#---------------------------------------------
running = True
window.every(1000, tick) # 1000ms=1s
window.mainloop()
running = False # it will end `while` loop