Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the life-time of a thread-local value in Python?

import threading

mydata = threading.local()

def run():
    # When will the garbage collector be able to destroy the object created
    # here? After the thread exits from ``run()``? After ``join()`` is called?
    # Or will it survive the thread in which it was created, and live until
    # ``mydata`` is garbage-collected?
    mydata.foo = object()

t = threading.Thread(target=run)
t.start()
t.join()
like image 406
Carlos Valiente Avatar asked Sep 25 '09 16:09

Carlos Valiente


People also ask

What is thread life cycle in Python?

A Python thread may progress through three steps of its life-cycle: a new thread, a running thread, and a terminated thread. While running, the thread may be executing code or may be blocked, waiting on something such as another thread or an external resource.

What is threading local () in Python?

The . local() method returns a local thread object with data that is specific to that thread. This data can be anything from arbitrary numbers to session-specific information like usernames.

Are local variables thread-safe in Python?

Local variables and parameters are always thread-safe. Instance variables, class variables, and global variables may not be thread-safe (but they might be).


1 Answers

Here is my answer, since I am failing to see the conclusion in the previous answers.

I started wondering the same thing and tried a test program that is similar to the ones in other answers and my conclusion was that they do get GCed sooner than the end of the program, which means, these references can be determined as garbage once the thread itself dies.

import time
import threading
import gc

data = threading.local()

class Resource(object):
    def __init__(self):
        self.name = threading.currentThread().name
        print 'create: %s' % self.name

    def __del__(self):
        print 'delete: %s' % self.name

def access_thlocal():
    data.key = Resource()

for i in range(0, 10):
    threading.Thread(target=access_thlocal).start()
time.sleep(1)
print "Triggering GC"
gc.collect()
time.sleep(1)

The output:

create: Thread-1
create: Thread-2
delete: Thread-1
create: Thread-3
delete: Thread-2
create: Thread-4
delete: Thread-3
create: Thread-5
delete: Thread-4
create: Thread-6
delete: Thread-5
create: Thread-7
delete: Thread-6
create: Thread-8
delete: Thread-7
create: Thread-9
delete: Thread-8
create: Thread-10
delete: Thread-9
Triggering GC
delete: Thread-10

As you can see, the delete's seem to happen as soon as the thread dies.

like image 158
haridsv Avatar answered Sep 18 '22 16:09

haridsv