Python 2.7,thread.Timer生成太多垃圾线程未回收

标签 python multithreading timer

我在我的Windows上运行一个Python示例代码,每次执行计时器线程后,都会创建一个新线程,如下所示,但旧线程从未回收,线程数量不断增加真的很烦人,我是担心我的软件迟早会耗尽整个电脑的内存。我看到很多人也遇到了同样的问题,用pydev调试时,最终会报“TclError: out of stack space”!

这是我的pydev调试堆栈的列表,它会不断增加,直到“堆栈空间不足”,从堆栈 View 中,我看到线程数量非常疯狂......

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?)

下面是我的代码,它设置一个计时器,然后调用函数“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()

最佳答案

您的代码无法在我的 Python 上执行。一旦计时器线程被触发,就不需要取消它。只需制作一个新的即可。此外,将第一个 Timer 创建放在初始化例程中并等待其执行处理函数会更干净:

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()

所有计时器线程在触发后都会终止,稍后将被垃圾收集。它们不会填满所有可用内存。

关于Python 2.7,thread.Timer生成太多垃圾线程未回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53079711/

相关文章:

python - 通过索引从 Pandas DataFrame 访问单个值的简洁方法

python - jupyter 模块未找到错误 : No module named matplotlib

javascript - 带有 JavaScript 的编程 Python 浏览器

java - 如何同步两个方法?

python - 从二维数组 python 中删除引号

java - SecureRandom 流具有多个线程的奇怪行为

java - Threadpoolexecutor 不更新并发 HashMap

multithreading - 如何在一个对象内模拟一个定时器,该定时器会周期性地改变该对象?

java - 在 Glassfish/Payara 上禁用或隐藏 "ejb-timer-service-app"

ios - 在后台运行 ios 应用程序