I would like to kill somehow a running thread from my GUI application via setting an event, but I can't use a for loop in my thread so I need some other solution to check the event
I have the following situation. In a tkinter gui when I click a button I start a thread and set a global variable.
self.thread = StoppableThread(caller=self)
self.thread.start()
is_running = 1
When I next click the button I check the global variable state and if it is already set I send a stop request:
if is_running:
is_running = 0
self.thread.stop()
This is my thread class:
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
Everything works if I change the while to a for loop, but because in this point in my business logic I doesn't have anything to loop for I need to check somehow different the state of the self.stopped(). Is there any way to check it in the while loop?
Or how can I achive this? I tried to use process instead of thread but it wasnt worked because of an error 'process can't pickle tkinter'.
Thank you for any help
CodePudding user response:
This loop will run forever until you set the flag:
def run(self):
while not self.stopped():
sleep(1)
print('Test')
You don't actually need an event. A simple Boolean will do.
FOLLOWUP
Here's an example based on your code that shows how this works:
import threading
from time import sleep
class StoppableThread(threading.Thread):
def __init__(self, caller=None):
super(StoppableThread, self).__init__()
self._stop_event = False
self.caller = caller
def stop(self):
self._stop_event = True
def stopped(self):
return self._stop_event
def run(self) -> None:
while not self.stopped():
sleep(1)
print('Test')
print("exited")
thread = StoppableThread(caller=None)
thread.start()
sleep(5)
thread.stop()
sleep(1)
print("program ending")