Я запускаю образец кода Python в своих окнах, после каждого выполнения потока таймера создается новый поток, как показано ниже, но старый никогда не перерабатывается, это действительно раздражает, количество потоков продолжает расти, и я боюсь, что мое программное обеспечение рано или поздно займет всю память компьютера. Я вижу, что многие другие также сталкивались с той же проблемой, при отладке с помощью pydev в конце концов будет сообщено «TclError: не хватает места в стеке»!
Вот список моего стека отладки pydev, он будет увеличиваться и увеличиваться до тех пор, пока "не закончится пространство стека", из представления стека я вижу, что количество потоков невероятно сумасшедшее ...
Thread-1913 - pid_9200_id_155817632
Thread-1915 - pid_9200_id_156052840
Thread-1917 - pid_9200_id_156052112
Thread-1919 - pid_9200_id_156326208
Thread-1921 - pid_9200_id_156326264
Ошибка, о которой сообщает pydev, выглядит следующим образом:
pydev debugger: starting (pid: 9200)
Exception in thread Thread-1921:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 1073, in run
self.function(*self.args, **self.kwargs)
File "D:\work\tools\eclipseWorkspace\timerTest.py", line 46, in handle_function
self.hFunction()
File "D:\work\tools\eclipseWorkspace\timerTest.py", line 56, in printer
lab['text'] = clock
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1337, in __setitem__
self.configure({key: value})
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1330, in configure
return self._configure('configure', cnf, kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1321, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
TclError: out of stack space (infinite loop?)
Ниже мой код, он устанавливает таймер, а затем вызывает функцию "цикл".
from threading import Timer, Thread, Event
from datetime import datetime
import Tkinter as tk
app = tk.Tk()
lab = tk.Label(app, text = "Timer will start in a sec")
lab.pack()
class perpetualTimer():
def __init__(self, t, hFunction):
self.t = t
self.hFunction = hFunction
self.thread = Timer(self.t, self.loop)
def loop(self):
self.hFunction()
self.thread = Timer(self.t, self.loop)
self.thread.start()
def start(self):
self.thread.start()
def printer():
tempo = datetime.today()
clock = "{}:{}:{}".format(tempo.hour, tempo.minute, tempo.second)
try:
lab['text'] = clock
except RuntimeError:
exit()
t = perpetualTimer(0.1, printer)
t.start()
app.mainloop()
Привет @BryanOakley, я просто использую этот код, чтобы показать свою проблему, мне действительно не нужна функция «часы».
Ваш код не выполняется на моем Python. Нет необходимости отменять поток таймера после его запуска. Просто сделай новый. Кроме того, намного проще просто поместить первое создание таймера в процедуру инициализации и дождаться, пока это выполнит функцию обработки:
class perpetualTimer():
def __init__(self, t, hFunction):
self.t = t
self.hFunction = hFunction
self.thread = Timer(self.t, self.handle_function)
def handle_function(self):
self.hFunction()
self.thread = Timer(self.t, self.handle_function)
self.thread.start()
def start(self):
self.thread.start()
Все потоки таймера завершаются после запуска и позже будут собраны мусором. Они не заполнят всю доступную память.
Привет, Джонатан, согласен, нет необходимости добавлять self.thread.cancel (), это было просто для отладки. Но ваш код работает так же, как и мой, он генерирует много мусорных потоков, я не вижу ни одного из них переработанного, но они все увеличиваются и увеличиваются, внешность никогда не достигает конца ...
Я только что внес некоторые изменения на основе ваших отзывов. Также я изменил время расписания с 1 секунды на 0,1, после чего я вижу, что идентификатор потока увеличился до 1929 «Thread-1929 - pid_4060_id_147668888»
Если все, что вы делаете, это обновляете часы, вам определенно не нужно использовать потоки. Вы хотите решить проблему с потоками или открыты для других решений?