I have some threads created with the class
import time, threading
class SetInterval:
def __init__(self, interval, function):
"""SetInterval
Args:
interval (int number): seconds
function (function): function to be executed after x seconds
"""
self.interval = interval
self.function = function
self.stopEvent=threading.Event()
thread=threading.Thread(target=self.__setInterval)
thread.start()
def __setInterval(self) :
"""while interval, execute passed func every time passed interval secs
"""
nextTime = time.time() self.interval
while not self.stopEvent.wait(nextTime - time.time()) :
nextTime = self.interval
try: self.function()
except Exception as e: print(f'Exception [__setInterval]: ', e)
def cancel(self):
"""sending class.cancel() stops the thread
"""
print('[SetInterval][Cancel]: event canceled.')
self.stopEvent.set()
any way to stop them all once i close my program with tkinter? because after it's compiled it keeps the threads open if you don't cancel everything before..
My tries...
def kill_all_threads():
for thread in threading.enumerate():
if not "MainThread" in thread.name:
thread._Thread__stop()
# AttributeError: 'Thread' object has no attribute '_Thread__stop'
def kill_all_threads():
for thread in threading.enumerate():
if not "MainThread" in thread.name:
thread.__stop()
# AttributeError: 'Thread' object has no attribute '__stop'
def kill_all_threads():
for thread in threading.enumerate():
if not "MainThread" in thread.name:
thread.stopEvent.set()
# AttributeError: 'Thread' object has no attribute 'stopEvent'
In that way I call in main tkinter app
self.tkinter_thread = SetInterval(1, some_func)
#-----------------------------------------------------
self.low_health_interval = SetInterval(0.2, some_func)```, thats my
def kill_all_threads():
print('kill_all_threads')
for t in threading.enumerate():
if isinstance(t, SetInterval):
print("Canceling", t)
t.cancel()
t.join()
CodePudding user response:
None of the methods you've tried exist on Thread
objects, and SetInterval
isn't a Thread
either.
You'll have a better time if you derive directly from threading.Thread
, because then you can use isinstance
with threading.enumerate()
:
import time, threading
class IntervalThread(threading.Thread):
def __init__(self, interval, function):
threading.Thread.__init__(self)
self.interval = interval
self.function = function
self._stop_event = threading.Event()
def run(self):
next_time = time.time() self.interval
while not self._stop_event.wait(next_time - time.time()):
next_time = self.interval
try:
self.function()
except Exception as e:
print(f"Exception [__setInterval]: ", e)
def cancel(self):
self._stop_event.set()
def main():
IntervalThread(1, lambda: print("hello")).start()
IntervalThread(2, lambda: print("world")).start()
time.sleep(5)
for t in threading.enumerate():
if isinstance(t, IntervalThread):
print("Canceling", t)
t.cancel()
t.join()
if __name__ == "__main__":
main()
This prints out (e.g.)
hello
hello
world
hello
hello
world
hello
Canceling <IntervalThread(Thread-1, started 123145357873152)>
Canceling <IntervalThread(Thread-2, started 123145374662656)>
CodePudding user response:
You can always set the threads to be daemon threads which will automatically shutdown when the parent thread exits.
thread=threading.Thread(target=self.__setInterval, daemon=True)