When to use thread local memory in Python?

Sebastian Eydam

I am just starting with Python and stumbled upon the thread local memory. I wrote a small program that uses threads:

#!/usr/bin/env python3

import logging
import signal
import threading
import time

class WorkerThread(threading.Thread):
    def __init__(self, idx):
        threading.Thread.__init__(self)
        self.thread_index = idx
        self.thread_alive = True

    def run(self):
        logging.info(f'Thread {self.thread_index} is starting up!')

        while self.thread_alive:
            logging.info(f'Thread {self.thread_index} is still running.')
            time.sleep(1)

        logging.info(f'Thread {self.thread_index} is stopping!')

    def kill(self):
        self.thread_alive = False

def main():
    logging.basicConfig(format = '%(levelname)s: %(message)s', level = logging.INFO)

    def signal_handler(sig, frame):
        logging.info('Ctrl+c pressed, killing threads and shutting down ...')
        nonlocal threads
        for thread in threads:
            thread.kill()

    signal.signal(signal.SIGINT, signal_handler)

    logging.info('Signal handler registered, starting threads ...')

    threads = []
    for i in range(0, 3):
        thread = WorkerThread(i)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    signal.signal(signal.SIGINT, signal.SIG_DFL)

if __name__ == '__main__':
    main()

This program works as expected and prints something like:

> python3 main.py
INFO: Signal handler registered, starting threads ...
INFO: Thread 0 is starting up!
INFO: Thread 0 is still running.
INFO: Thread 1 is starting up!
INFO: Thread 2 is starting up!
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
INFO: Thread 2 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 1 is still running.
INFO: Thread 0 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
^CINFO: Ctrl+c pressed, killing threads and shutting down ...
INFO: Thread 2 is stopping!
INFO: Thread 1 is stopping!
INFO: Thread 0 is stopping!

In this case the thread_index and thread_alive variables are specific for each thread as they are specific for each object. But there is also the threading.local() function that creates thread local memory. So I tried to use this, as I want my variables to be thread specific. I used it after I defined the class:

# imports and shebang

class WorkerThread(threading.Thread):
    thread_index = threading.local()
    thread_alive = threading.local()

# everything else stays the same

But using this does not change anything, the output stays the same. So my questions are:

  • is this thread local memory for another use case or did the first program only work by accident?
  • what are use cases for threading.local(), as creating object specific (non static) variables seem to work too?
Roman Konoval

threading.local() is for cases when you cannot or don't want to modify classes that implement threads.

In the above example you are in full control as you've created WorkerThread and you have started threads. So you know that you have an instance per running thread and you can store values in the instance that is bound to a thread. That's why your initial example worked. It works correctly in this regard.

But it is not always the case that you control threads. Sometimes threads are started by the library or framework and you only provide some code that will be run in these threads. In that case you cannot modify Thread classes and add thread specific variables to them.

Let's take an example of a multithreaded web server. You provide functions that are supposed to process incoming requests. You do not create all the infrastructure to listen on the socket, parse http request etc. All these activities are handled by the framework. It starts a pool of threads for you and when there's incoming request the framework parses it and invokes the handler you've provided using a thread from the pool.

In this case let's imagine you want to store some context for the request that is being processed (for example the currently logged in user) so that you can access it during request processing but do not need to pass it around in every function explicitly. You can't add this currentUser variable to a thread class as you don't have control over it. But you can use threading.local() to store it. And requests that are concurrently processed in multiple threads will have their own copies of that.

The same is applicable for your own creations. When the program becomes more complex and you need to separate infrastructure code (managing threads) from the logic of your application it may happen that you do not want to add a thread specific variables to thread classes and use threading.local() instead.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Python Queues memory leaks when called inside thread

From Dev

Python 2.7: Thread local storage's instantiation when first accessed?

From Dev

Python 2.7: Thread local storage's instantiation when first accessed?

From Dev

Amount of local memory per CUDA thread

From Dev

Java: Thread local memory allocation and scalability

From Dev

How to release heap memory of thread local storage

From Dev

Optimizing local memory use with OpenCL

From Dev

Killing Thread and releasing memory in Python

From Dev

Killing Thread and releasing memory in Python

From Dev

What is the best way to use pthread and mutex lock to protect a memory when it is modified by one thread and read by other threads?

From Dev

Is it safe to use memory_order_relaxed to load an atomic variable, when in the only thread that writes to that variable?

From Dev

When thread in Java is removed from memory?

From Dev

Use thread local data with PLINQ AsParallel()?

From Dev

Use thread local data with PLINQ AsParallel()?

From Dev

Memory use local vars over inline Java

From Dev

opencl - use image object with local memory

From Dev

When is a `thread_local` global variable initialized?

From Dev

Increase Spark memory when using local[*]

From Dev

when the memory is cleared on stack for a local function?

From Dev

when the memory is cleared on stack for a local function?

From Java

Spring when to use in memory authentication

From Dev

Do I need both a local and global memory barrier when writing form local memory to global

From Dev

Python terminate a thread when it is sleeping

From Dev

when will main thread exit in python

From Dev

when will main thread exit in python

From Dev

Python terminate a thread when it is sleeping

From Dev

How to set the max thread a python script could use when calling from shell

From Dev

how to block a thread without select when using shared memory?

From Dev

Does a thread's cache get flushed to main memory when it exits?

Related Related

  1. 1

    Python Queues memory leaks when called inside thread

  2. 2

    Python 2.7: Thread local storage's instantiation when first accessed?

  3. 3

    Python 2.7: Thread local storage's instantiation when first accessed?

  4. 4

    Amount of local memory per CUDA thread

  5. 5

    Java: Thread local memory allocation and scalability

  6. 6

    How to release heap memory of thread local storage

  7. 7

    Optimizing local memory use with OpenCL

  8. 8

    Killing Thread and releasing memory in Python

  9. 9

    Killing Thread and releasing memory in Python

  10. 10

    What is the best way to use pthread and mutex lock to protect a memory when it is modified by one thread and read by other threads?

  11. 11

    Is it safe to use memory_order_relaxed to load an atomic variable, when in the only thread that writes to that variable?

  12. 12

    When thread in Java is removed from memory?

  13. 13

    Use thread local data with PLINQ AsParallel()?

  14. 14

    Use thread local data with PLINQ AsParallel()?

  15. 15

    Memory use local vars over inline Java

  16. 16

    opencl - use image object with local memory

  17. 17

    When is a `thread_local` global variable initialized?

  18. 18

    Increase Spark memory when using local[*]

  19. 19

    when the memory is cleared on stack for a local function?

  20. 20

    when the memory is cleared on stack for a local function?

  21. 21

    Spring when to use in memory authentication

  22. 22

    Do I need both a local and global memory barrier when writing form local memory to global

  23. 23

    Python terminate a thread when it is sleeping

  24. 24

    when will main thread exit in python

  25. 25

    when will main thread exit in python

  26. 26

    Python terminate a thread when it is sleeping

  27. 27

    How to set the max thread a python script could use when calling from shell

  28. 28

    how to block a thread without select when using shared memory?

  29. 29

    Does a thread's cache get flushed to main memory when it exits?

HotTag

Archive