Falmarri
Falmarri

Reputation: 48587

Python threads garbage collection

Is a running thread eligable for garbage collection if the thread object is reasigned? For example:

class A(threading.Thread)
    def run():
        while True:
            #Do stuff


a = A()
a.start()
time.sleep(60)
a = A()

at this point, even though thread A is still doing stuff, can the interpreter destroy the original A() thread? If it does, is there a way to prevent this from happening?

Upvotes: 8

Views: 4818

Answers (3)

dnozay
dnozay

Reputation: 24344

Threads won't get garbage collected if there is a reference to the object kept somewhere.

see https://hg.python.org/cpython/file/2.7/Lib/threading.py, it keeps tabs on thread objects.

# Active thread administration
_active_limbo_lock = _allocate_lock()
_active = {}    # maps thread id to Thread object
_limbo = {}

The threading module keeps references in module variables. When you call threading.enumerate() you are iterating over the same variables.

When you call start() it inserts a reference to the Thread object in the module variable and when run() terminates, it cleans up the reference.

Upvotes: 4

Jochen Ritzel
Jochen Ritzel

Reputation: 107686

Threads wont get deleted like that, but I guess the problem you have is that threads disappear for no reason? A unhandled Exception will kill a thread without affecting the main thread! It only prints the traceback to stderr, but you might not see that ...

Upvotes: 4

Robert
Robert

Reputation: 6540

My guess is no. There's still a reference to the thread in whatever structure Python uses to keep track of things. I'll test it out, but I'd be astonished if it didn't work.

EDIT Check it out:

#!/usr/bin/env python
import threading, time

class A(threading.Thread):
    def __init__(self, name):
            threading.Thread.__init__(self)
            self.name=name
            self.count=0
    def run(self):
            while self.count<10:
                    print self.name, "Running!"
                    time.sleep(1)
                    self.count+=1

a=A("first")
a.start()
time.sleep(5)
a=A("second")
a.start()
first Running!
first Running!
first Running!
first Running!
first Running!
second Running!
first Running!
second Running!
first Running!
first Running!
second Running!
first Running!
second Running!
first Running!
second Running!
second Running!
second Running!
second Running!
second Running!
second Running!

Upvotes: 5

Related Questions