Table of contents
What Is a Thread?
A thread is a way to run multiple tasks concurrently in the same program.
Real-life example:
Let’s say you are going camping with friends, and you are the driver. In this example, we need to look at three key things:
Project - What is our goal?
- Our goal is to get to the destination safely.
Process - How are we going to safely arrive at the destination?
- It depends on the driver
Thread - What are the requirements?
- The driver should be able to look at the navigation and drive the car.
Therefore, there could be three ways to get to the destination.
I (main thread) finds the route by myself, but I can’t do driving and looking at the map at the same time, which means I need to stop and look at the map. This results in longer time to arrive.
I (process 1) can ask a friend (process 2) for a route that does not go on a trip together. However, this way seems like unproductive.
I (main thread) have a navigation (sub thread) that shares data and memory with me. This way is the most EFFICIENT ← using multi thread.
Creating a Thread
Basic format:
# Thread library
import threading
def thread_func():
# your code
# Create a thread
x = threading.Thread(target=thread_func, args=())
# Start a thread
x.start()
Let’s create one:
import logging
import threading
import time
# Thread function
def thread_func(name):
logging.info("Sub-Thread %s: starting", name)
time.sleep(3)
logging.info("Sub-Thread %s: finishing", name)
# main
if __name__ == "__main__":
format = "%(asctime)s: %(message)s"
logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
logging.info("Main-Thread: before creating thread")
x = threading.Thread(target=thread_func, args=('First',))
logging.info("Main-Thread: before running thread")
x.start()
logging.info("Main-Thread: wating for the thread to finish")
logging.info("Main-Thread: All done!")
Output:
10:26:33: Main-Thread: before creating thread
10:26:33: Main-Thread: before running thread
10:26:33: Sub-Thread First: starting
10:26:33: Main-Thread: wating for the thread to finish
10:26:33: Main-Thread: All done!
10:26:36: Sub-Thread First: finishing
You may wonder why sub-thread finishes after the main thread finishes. If you want your main thread to wait for the sub-thread to end, you can use join()
.
x.start()
x.join()
Output:
10:26:59: Main-Thread: before creating thread
10:26:59: Main-Thread: before running thread
10:26:59: Sub-Thread First: starting
10:27:02: Sub-Thread First: finishing
10:27:02: Main-Thread: wating for the thread to finish
10:27:02: Main-Thread: All done!
Daemon Thread
Like a daemon, a daemon thread does not perform important tasks (low priorty). It runs in a background, doing some small works, such as garbage collecting and auto saving. These tasks are not something we can see.
Characteristics of daemon thread:
Background execution.
Automatically terminated when the main thread finishes even if they haven’t completed tasks.
Using Daemon Thread
x = threading.Thread(target=thread_func, args=('First', range(20000)), daemon=True)
It’s not a big deal. We can set daemon=True
to make it a daemon thread.