Как остановить поток в python
Помогите решить задачу: есть кнопка Play, при нажатии она меняет значение на Stop, и создается поток, в котором происходит цикл. Как сделать так, чтобы при клике по кнопке со значением Stop поток останавливался? А при клике по кнопке со значением Play - начинался?
import tkinter as tk
import threading
import time
import sys
def main():
if button_1['text'] == 'Play':
button_1['text'] = 'Stop'
thread = threading.Thread(target=run)
thread.start()
else:
button_1['text'] = 'Play'
sys.exit()
def run():
counter = 1
while counter <= 5:
print(counter)
counter += 1
time.sleep(0.5)
window = tk.Tk()
button_1 = tk.Button(window, text='Play', command=main)
button_1.pack()
window.mainloop()
Метод sys.exit() не подходит, так как он ждет пока завершится цикл и только потом срабатывает.
Ответы (3 шт):
Поток остановить невозможно. Но можно передать так называемый сигнал потоку что ему нужно остановиться. Этим сигналом может быть простая глобальная переменная, котороя будет проверяться в цикле while True.
Вот как это может выглядить:
import tkinter as tk
import threading
import time
import sys
def main():
global thread_stop
if button_1['text'] == 'Play':
button_1['text'] = 'Stop'
thread_stop = False #Что-бы поток не остановился присваеваем False
thread = threading.Thread(target=run)
thread.start()
else:
button_1['text'] = 'Play'
thread_stop = True #Присваеваем значение True и завершаем поток
thread_stop = False
def run():
counter = 1
while counter <= 5:
if thread_stop == True: return #Останавливаем цикл
print(counter)
counter += 1
time.sleep(0.5)
window = tk.Tk()
button_1 = tk.Button(window, text='Play', command=main)
button_1.pack()
window.mainloop()
Таким образом при нажати на кнопку "Стоп", вам нужно будет присвоить переменной thread_stop значение True и поток остановиться, а при включении потока присвоить значение False.
Еще один способ:
import tkinter as tk
import threading
import time
import sys
counter = 1
def main():
global counter
if button_1['text'] == 'Play':
button_1['text'] = 'Stop'
thread = threading.Thread(target=run)
thread.start()
else:
button_1['text'] = 'Play'
counter = 1
def run():
global counter
while counter <= 5:
print(counter)
counter += 1
time.sleep(0.5)
if button_1['text'] == 'Play':
break
if counter > 5:
main()
break
window = tk.Tk()
button_1 = tk.Button(window, text='Play', command=main)
button_1.pack()
window.mainloop()
Из документации threading:
A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property or the daemon constructor argument.
Note: Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.
Поэтому точно так-же, как и в скрытом смысле этой цитаты, советую ознакомиться с классом Event.