Skip to content

Python Threading And Multiprocessing

Published On:
Jan 2, 2015
Last Updated:
Jan 2, 2015

Python supports threading. However, because of the GIL lock, only one thread is allowed to run at once. There Python threading supports concurrency, but not parallelism. This makes Python threading suitable for IO bound operations, but not for processor bound operations. Most threading functions are made available by adding the code import threading to the top of your Python script.

Gracefully Exiting Multiple Threads

I followed this example at regexprn.com for the most part, except I discovered the example code was buggy and had to make some tweaks, as outlined below.

import time
import threading
DEBUG = 0
class MyThread1(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# A flag to notify the thread that it should finish up and exit
self.kill_received = False
def run(self):
while not self.kill_received:
self.do_something()
def do_something(self):
# Do your thread logic here!
# Make sure to add some kind of pause as to not starve other threads
time.sleep(5.0)
# END | def do_something(self):
# END | class MyThread1(threading.Thread):
# @brief main() function for script.
# @details Starts up the individual threads and controls their execution.
def main(args):
threads = []
#----- START THE THREADS -----#
# Start the internet check thread
print 'Starting MyThread1...'
t = MyThread1()
threads.append(t)
t.start()
print 'MyThread1 started...'
# Start the knob control thread
print 'Starting MyThread2...'
t = MyThread2()
threads.append(t)
t.start()
print 'MyThread2 started...'
#----- MONITOR THE THREADS -----#
while len(threads) > 0:
if DEBUG:
print 'len(threads) = ', len(threads)
try:
if DEBUG:
print 'In try block.'
# Join all threads using a timeout so it doesn't block
# Filter out threads which have been joined or are None
for i in range(len(threads)):
# Make sure thread still exists
if threads[i] is not None:
if DEBUG:
print 'Attemping to join()...'
threads[i].join(1)
if threads[i].isAlive() is False:
if DEBUG:
print 'isAlive() is False, removing thread from list...'
threads.pop(i)
if DEBUG:
print 'Exiting try block...'
except KeyboardInterrupt:
print "Ctrl-c received! Sending kill to threads..."
for t in threads:
t.kill_received = True
except Exception as e:
print "Unknown exception caught! Sending kill to threads...", e
for t in threads:
t.kill_received = True
print 'main() is returning...'
if __name__ == '__main__':
main(sys.argv)

Examples

The Columbus Radio project uses multiple Python threads for the UI control. The code is in the ColumbusRadio repo on GitHub. The threads should gracefully exit if Ctrl-C is pressed in the terminal while they are running.