Introduction
In Computer Science, a thread is defined as the smallest unit of execution with the independent set of instructions. In simple terms, a thread is a separate flow of execution, it means that our program will have two things happening at once, but for most Python 3 implementations the different threads do not actually execute at the same time.
The advantage of thread programming is that it allows a user to run different parts of the program in a concurrent manner and make the design of his/her program simpler.
During thread programming, different processors run on a single programme and each one of them performs an independent task simultaneously. However, if we want to perform multiprocessing, then we need to execute our code in a different programming language or need to use the multiprocessing module.
In the CPython implementation of Python, interactions are made with the Global Interpreter Lock (GIL) which always limits one Python thread to run at a time. In threading, Tasks that spend much of their time waiting for external events are generally good candidates for threading. These are all true in the case when the code is written in Python. However, in the case of thread programming in C other than Python, they have the ability to release GIL and run in a concurrent manner.
Let us see how to start a thread in Python.
To know about insertion sort python click here.
Starting a Thread:
Now from the above introduction part, we’ve got an idea of what a thread is, let’s learn how to make one. The Python Standard Library contains a module named threading which comprises all the basics needed to understand the process of threading better. By this module, we can easily encapsulate threads and provide a clean interface to work with them. If we want to start a separate thread, first we need to create a Thread instance and then implement .start():

If we look around the logging statements, we can see clearly that the main section is creating and starting the thread:
| t = threading.Thread(target=thread_function, args=(1,))t.start() |
When a Thread is created, a function and a list of arguments to that function are passed. In the above example, thread_function() is being run and 1 is passed as an argument. The function, however, simply logs messages with a time.sleep() in between them.
Working with Multiple Threads:
The example code so far has only been working with two threads: the main thread and one we started with the threading. Thread object. Frequently, we’ll want to start a number of threads and have them do interesting work. The process of executing multiple threads in a parallel manner is called multi-threading. It enhances the performance of the program and Python multithreading is quite easy to learn.
Let us start understanding multi-threading using the example we used earlier:

This code will work in the same way as it was in the process to start a thread. First, we need to create a Thread object and then call the .start() object. The program then keeps a list of Thread objects. It then waits for them using .join(). The threads are sequenced in the opposite order in this example. This is because multi-threading generates different orderings. The Thread x: finishing message informs when each of the thread is done. The thread order is determined by the operating system, so it is essential to know the algorithm design that uses the threading process.
Thread Pool Executor:
Using a ThreadpoolExecutor is an easier way to start up a group of threads. It is contained in the Python Standard Library in concurrent futures one can create it as a context manager using the help of with statement. It will help in managing and destructing the pool.





