This blog covers the basics of Multithreading in Python programming language. Just like multiprocessing, multithreading is a way of achieving multitasking. In multithreading, the concept of threads is used.
Let us first understand the concept of thread..
What is Thread?
In computing, a process is an instance of a computer program that is being executed. Any process has 3 basic components:
- An executable program.
- The associated data needed by the program (variables, work space, buffers, etc.)
- The execution context of the program (State of process)
- A thread is an entity within a process that can be scheduled for execution. Also, it is the smallest unit of processing that can be performed in an OS (Operating System).
A thread is the smallest unit of a program or process executed independently or scheduled by the Operating System. In the computer system, an Operating System achieves multitasking by dividing the process into threads. A thread is a lightweight process that ensures the execution of the process separately on the system. In Python 3, when multiple processors are running on a program, each processor runs simultaneously to execute its tasks separately.
In simple words, a thread is a sequence of such instructions within a program that can be executed independently of other code. For simplicity, you can assume that a thread is simply a subset of a process.
A thread contains all this information in a Thread Control Block (TCB):
Thread Identifier: Unique id (TID) is assigned to every new thread
Stack pointer: Points to thread’s stack in the process. Stack contains the local variables under thread’s scope.
Program counter: a register which stores the address of the instruction currently being executed by thread.
Thread state: can be running, ready, waiting, start or done.
Thread’s register set: registers assigned to thread for computations.
Parent process Pointer: A pointer to the Process control block (PCB) of the process that the thread lives on.
Multithreading in Python:
Multithreading is defined as the ability of a processor to execute multiple threads concurrently.
Multithreading refers to concurrently executing multiple threads by rapidly switching the control of the CPU between threads (called context switching).
Multithreading aims to perform multiple tasks simultaneously, which increases performance, speed and improves the rendering of the application.
Multithreading in Python programming is a well-known technique in which multiple threads in a process share their data space with the main thread which makes information sharing and communication within threads easy and efficient. Threads are lighter than processes. Multi threads may execute individually while sharing their process resources. The purpose of multithreading is to run multiple tasks and function cells at the same time.
Benefits of Multithreading in Python
Following are the benefits to create a multithreaded application in Python, as follows:
- It ensures effective utilization of computer system resources.
- Multithreaded applications are more responsive.
- It shares resources and its state with sub-threads (child) which makes it more economical.
- It makes the multiprocessor architecture more effective due to similarity.
- It saves time by executing multiple threads at the same time.
- The system does not require too much memory to store multiple threads
Python Multithreading vs Multiprocessing
To understand processes and threads, consider this scenario: An .exe file on your computer is a program. When you open it, the OS loads it into memory, and the CPU executes it. The instance of the program which is now running is called the process.
Every process will have 2 fundamental components:
- The Code
- The Data
Now, a process can contain one or more sub-parts called threads. This depends on the OS architecture. You can think about a thread as a section of the process which can be executed separately by the operating system.
In other words, it is a stream of instructions which can be run independently by the OS. Threads within a single process share the data of that process and are designed to work together for facilitating parallelism.
Python supports constructs for both multiprocessing as well as multithreading. In this tutorial, you will primarily be focusing on implementing multithreaded applications with python. There are two main modules which can be used to handle threads in Python:
- The thread module, and
- The threading module
The Thread Module:
However, the thread module has long been deprecated. Starting with Python 3, it has been designated as obsolete and is only accessible as __thread for backward compatibility. You should use the higher-level threading module for applications which you intend to deploy. The thread module has only been covered here for educational purposes.
The syntax to create a new thread using this module is as follows:
The Threading Module:
This module is the high-level implementation of threading in python and the de facto standard for managing multithreaded applications. It provides a wide range of features when compared to the thread module.
Here is a list of some useful functions defined in this module:
|activeCount()||Returns the count of Thread objects which are still alive|
|currentThread()||Returns the current object of the Thread class.|
|enumerate()||Lists all active Thread objects.|
|isDaemon()||Returns true if the thread is a daemon.|
|isAlive()||Returns true if the thread is still alive.|
|Thread Class methods|
|start()||Starts the activity of a thread. It must be called only once for each thread because it will throw a runtime error if called multiple times.|
|run()||This method denotes the activity of a thread and can be overridden by a class that extends the Thread class.|
|join()||It blocks the execution of other code until the thread on which the join() method was called gets terminated.|