classification
Title: memory leak with threads and enhancement of the timer class
Type: feature request Stage: test needed
Components: Interpreter Core Versions: Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ajaksu2, pitrou, thaar (3)
Priority: normal Keywords

Created on 2004-07-22 13:16 by thaar, last changed 2009-02-14 16:52 by pitrou.

Messages (3)
msg21751 - (view) Author: Tobias Haar (thaar) Date: 2004-07-22 13:16
If i use the Timer cyclically the  memory becomes
always less.


I found following problems::

1.) The thread is not clean deleted.=>
file:threading.py  class: Thread methode:__delete

del _active[_get_ident()] only delete the thead from
the list, not the thead self.  I think the call of the
destructor of the c++ based library need a explicit del.

The problem will be fixed with following lines:

    def __delete(self):
        _active_limbo_lock.acquire()
        t=_active[_get_ident()]
        del _active[_get_ident()]
        del t
        _active_limbo_lock.release()

2.) A cyclic timer is a needed feature and it should
not use a new thread every time.

So i made following enhancement (parameter cyclic) in the 
file:threading.py  class: _Timer  

class _Timer(Thread):
    """Call a function after a specified number of seconds:

    t = Timer(30.0, f, args=[], kwargs={})
    t.start()
    t.cancel() # stop the timer's action if it's still
waiting
    """

    def __init__(self, interval, function, cyclic=0,
args=[], kwargs={}):
        Thread.__init__(self)
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.finished = Event()
        self.cyclic= Event()
        if cyclic:
            self.cyclic.set()

    def cancel(self):
        """Stop the timer if it hasn't finished yet"""
        self.cyclic.clear()
        self.finished.set()

    def run(self):
        flag =1
        while flag:
            self.finished.wait(self.interval)
            if not self.finished.isSet():
                self.function(*self.args, **self.kwargs)
            if not self.cyclic.isSet():
                self.finished.set()
                flag = 0         



msg82079 - (view) Author: Daniel Diniz (ajaksu2) Date: 2009-02-14 14:46
Can't quite understand what the problem is supposed to be, comments?
msg82090 - (view) Author: Antoine Pitrou (pitrou) Date: 2009-02-14 16:52
I can't understand problem number 1 either. I suspect it is a
misunderstanding by the poster, since he is talking about a "destructor
of the c++ based library" and there's no c++ code in the interpreter.

As for number 2, it is a legitimate feature request. However, since the
current Timer class is very inefficient (one separate thread for each
timer), it would make sense to rephrase it as a more general suggestion
to re-implement the Timer class using a single background thread and a
heapq-based priority queue. It would be a good project for someone
wanting to start contributing to the interpreter.
History
Date User Action Args
2009-02-14 16:52:19pitrousetnosy: + pitrou
messages: + msg82090
2009-02-14 14:46:07ajaksu2settype: feature request
stage: test needed
messages: + msg82079
nosy: + ajaksu2
versions: + Python 2.7, - Python 2.3
2004-07-22 13:16:52thaarcreate