Using the threading
module, a new thread of execution may be started by creating a new threading.Thread
and assigning it a function to execute:
import threading
def foo():
print "Hello threading!"
my_thread = threading.Thread(target=foo)
The target
parameter references the function (or callable object) to be run. The thread will not begin execution until start
is called on the Thread
object.
Starting a Thread
my_thread.start() # prints 'Hello threading!'
Now that my_thread
has run and terminated, calling start
again will produce a RuntimeError
. If you'd like to run your thread as a daemon, passing the daemon=True
kwarg, or setting my_thread.daemon
to True
before calling start()
, causes your Thread
to run silently in the background as a daemon.
Joining a Thread
In cases where you split up one big job into several small ones and want to run them concurrently, but need to wait for all of them to finish before continuing, Thread.join()
is the method you're looking for.
For example, let's say you want to download several pages of a website and compile them into a single page. You'd do this:
import requests
from threading import Thread
from queue import Queue
q = Queue(maxsize=20)
def put_page_to_q(page_num):
q.put(requests.get('http://some-website.com/page_%s.html' % page_num)
def compile(q):
# magic function that needs all pages before being able to be executed
if not q.full():
raise ValueError
else:
print("Done compiling!")
threads = []
for page_num in range(20):
t = Thread(target=requests.get, args=(page_num,))
t.start()
threads.append(t)
# Next, join all threads to make sure all threads are done running before
# we continue. join() is a blocking call (unless specified otherwise using
# the kwarg blocking=False when calling join)
for t in threads:
t.join()
# Call compile() now, since all threads have completed
compile(q)
A closer look at how join()
works can be found here.
Create a Custom Thread Class
Using threading.Thread
class we can subclass new custom Thread class.
we must override run
method in a subclass.
from threading import Thread
import time
class Sleepy(Thread):
def run(self):
time.sleep(5)
print("Hello form Thread")
if __name__ == "__main__":
t = Sleepy()
t.start() # start method automatic call Thread class run method.
# print 'The main program continues to run in foreground.'
t.join()
print("The main program continues to run in the foreground.")