Topics

Introduction to Multithreading

Welcome to a tutorial in Multithreading in Python. Here you will learn the concept of multithreading and threads can be implemented in Python.

Threads

In Python, threads are lightweight processes (i.e. subparts of a large process) that can run concurrently in parallel with one another, in which each thread can perform some task. They have usually contained n processes. More than one thread can exist within the same process. Within the same process, threads share memory and the state of the process.

 

Types of Thread

There are two kinds of threads:

  • Kernel-level threads
  • User level threads

In the table, a few differences between this two are highlighted.

Kernel-level threadsUser level Thread
It is recognized by the operating system.Not recognized by the operating system.
It is implemented by the operating system.It is implemented by a user of the system.
Its implementation is complex.Its implementation is simple and easy.
Solaris is an example herePosix is an example here
It requires hardware supportIt requires no hardware support

 

What is Multithreading?

In modern computers, some CPUs have multiple processing cores and each of these cores can run many threads simultaneously which gives us the ability to perform numerous tasks concurrently. As such, this process of running multiple Threads simultaneously or concurrently to perform tasks in parallel is known as Multithreading.

The following are the benefit of Multithreading.

Multiple threads within a process share the same data space, it can, however, share information or communicate with each other more effectively and more easily than if they were separate processes.

Individual Threads do not require much memory overhead, as they are cheaper in processes in terms of memory requirements.

Multithreaded programs tend to run faster on computer systems with multiple CPUs, because of the nature of being executed concurrently.

 

Time for an Example

Suppose, we did create a simple application for an Event's registration in which the attendees must register if they wish to attend the event. We have therefore a simple HTML form for the users to fill their data and a backend that is rather a single-thread application. Since the application is single-threaded, it can only process one request at a time. Now, what if the event is a "Coldplay's Music Concert" in which millions of people want to register. Thus, when processing one request at a time, will drastically slow down the performance.

Therefore, we have to make the application multi-threaded and start multiple threads inside it, thereby allowing parallel processing.

 

Multithreading in Python

The threading module is used when performing multithreading in Python. The threading module provides numerous functions or methods to implement multithreading in python easily.

Let’s learn about the modules first. The time module provides a time(), ctime(), and so on, functions that will be used to get the current system time another important function is the sleep(), which is used to suspend the execution of the current thread for several seconds.

Check out the example:

import time
print("Current time is: " + time.ctime())
print("Going to sleep for 3 seconds...")
time.sleep(3)
print("I am awake!")

Output:

Current time is: Sun Aug  7 17:00:54 2022
Going to sleep for 3 seconds...
I am awake!

In the example, we will use the threading module to start multiple threads.

import time
import threading

def thread1(i):
    time.sleep(3)
    print('No. printed by Thread 1: %d' %i)

def thread2(i):
    print('No. printed by Thread 2: %d' %i)
    
if __name__ == '__main__':
    
    t1 = threading.Thread(target=thread1, args=(10,))
    t2 = threading.Thread(target=thread2, args=(12,))
    # start the threads
    t1.start()
    t2.start()
    # join the main thread
    t1.join()
    t2.join()

Output:

No. printed by Thread 2: 12
No. printed by Thread 1: 10

From the above example, we imported the thread class using the import threading statement and the time module was imported. Also, to create a new thread, we create an object of the Thread class. And the following arguments were taken:

target: The function is going to be executed by the thread.

args: The arguments meant to be passed to the target function. As such we can pass multiple arguments separated by a comma.

In our example above, 2 threads were created with different target functions which are thread1(i) and thread2(i).

We used the start() method of the Thread class to start a thread. Also, the time.sleep() method of the time module was used to pause the execution of thread1 for 3 seconds.

Thus, if the thread starts, the current program (i.e. the main thread) also keeps on executing. Now, to prevent the main program from completing its execution until the thread execution is complete, the join() method can be used.

As a result, the current program will wait for the completion of t1and t2, so, it is only after their execution is finished that the remaining statements of the current program will get executed, that is the statement print('Execution completed.').