Multithreading
When we run a block of code, let’s say a ‘While’ loop, the program is now halted till this loop has reached completion. In other words, we cannot execute two blocks of code simultaneously. To achieve multitasking using programming we need to use threading, or specifically Multithreading. The concept of threading allows us to execute functions or parts of a program simultaneously.
To be precise while it may look like Python is executing blocks of code simultaneously, in reality when we use threading, Python executes the second block of code on another process. Python shifts back and forth with these processes with a certain time given for each process. However, the time gap between these is so small that it shifts between these processors so instantaneously that it appears to be happening concurrently.
Let’s explore some terms to understand Multithreading.
Term | Description |
Process | It is an instance of a program that is running on our system. |
Threads | It is created by a Process to handle subtasks for our Process. |
Consider an example, let’s say we are playing a video game. We have threads taking care of different parts of the game, like computing scores, playing a piece of background music, connecting to online servers, and many more. Or let’s say when we are building an application that has some text that gets updated everyone 1 minute; by using threads we can achieve this without halting our program entirely.
Some of the advantages of using Multithreaded applications are:
- This allows us for resource sharing amongst different threads, as they use the same address space.
- We can create responsive programs that can take user input or do some other operation while there is another lengthy operation going on.
- Creating different processes takes a long time and is also more expensive compared to using threads.
To work with Multithreading in Python we can use one of the two modules for threading. We have the “thread” and “threading” modules. The primary difference is that the “thread” module considers a thread as a function whereas the “threading” module considers a thread as an object. However, the “thread” module is considered deprecated.
Let’s look at a code snippet that iterates from 1 to 6 and sends each number of the iteration to a function. The function uses that number to represent a particular thread count. The function puts a thread to sleep for one second.
NOTE: We use the time module, to put a program to sleep, and the argument passed represents how many seconds it should sleep.
import threading, time from datetime import datetime def print_details(number): print(f"Thread {number} started at {datetime.now().time()} and is going to sleep for 1 second") time.sleep(1) print(f"Thread {number}, has finished sleeping at {datetime.now().time()}") # With threading for x in range(1, 6): t = threading.Thread(target=print_details, args=[x]) t.start()
As you can see all of the threads have begun simultaneously and ended together as well. The order of when each thread ends changes each time. The datetime module offers us the ability to get the current time and date, as well as other features, which we will explore in a later blog.
Do not worry about understanding every single aspect of the Threading function, we will explore them in detail in the upcoming blogs.
What have we learned?
- What is Multithreading?
- How does Python handle multiple threads?
- What is a Process and a Thread?
- What are the advantages of using Multithreaded applications?
- What modules can we use in Python to work with threading?