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?