Basic Concepts of Multithreading in Python


Multithreading is a programming concept where multiple threads are executed concurrently to improve the performance of applications. Threads are lightweight subprocesses that share the same memory space. Python's threading module provides tools to work with threads. This article introduces the basic concepts of multithreading and demonstrates how to use it in Python.

What is a Thread?

A thread is the smallest unit of a process that can be scheduled for execution. A Python program can have multiple threads running simultaneously, which can help in performing tasks like I/O-bound operations, background tasks, and more.

Creating Threads in Python

Threads in Python can be created using the threading module. There are two main ways to create threads:

  • Using the Thread class directly.
  • Creating a subclass of the Thread class.

Example 1: Creating Threads Using the Thread Class

In this example, we create two threads to perform simple tasks.

    import threading
    import time

    def print_numbers():
        for i in range(5):
            print(f"Number: {i}")
            time.sleep(1)

    def print_letters():
        for letter in "ABCDE":
            print(f"Letter: {letter}")
            time.sleep(1)

    thread1 = threading.Thread(target=print_numbers)
    thread2 = threading.Thread(target=print_letters)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    print("Both threads have finished")
        

Explanation:

  • threading.Thread(target=...): Creates a thread to execute the specified function.
  • start(): Starts the thread.
  • join(): Waits for the thread to finish.

Output:

    Number: 0
    Letter: A
    Number: 1
    Letter: B
    ...
    Both threads have finished
        

Example 2: Subclassing the Thread Class

We can also create threads by subclassing the Thread class and overriding its run() method.

    import threading
    import time

    class MyThread(threading.Thread):
        def __init__(self, name):
            super().__init__()
            self.name = name

        def run(self):
            for i in range(5):
                print(f"{self.name}: {i}")
                time.sleep(1)

    thread1 = MyThread("Thread-1")
    thread2 = MyThread("Thread-2")

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    print("All threads have completed")
        

Explanation:

  • MyThread: A subclass of threading.Thread.
  • run(): Contains the code to be executed by the thread.
  • start(): Starts the thread and calls the run() method.

Output:

    Thread-1: 0
    Thread-2: 0
    Thread-1: 1
    Thread-2: 1
    ...
    All threads have completed
        

Advantages of Multithreading

Multithreading can provide several benefits:

  • Improved application responsiveness.
  • Efficient use of system resources.
  • Better performance for I/O-bound tasks.
  • Easy implementation of background tasks.

Limitations of Multithreading in Python

Python's Global Interpreter Lock (GIL) prevents multiple native threads from executing Python bytecodes at the same time. This can limit the effectiveness of multithreading for CPU-bound tasks. For such tasks, multiprocessing is often a better choice.

Conclusion

Multithreading is a powerful tool for managing concurrent tasks in Python. It is particularly useful for I/O-bound tasks and improving application responsiveness. While Python's GIL may limit multithreading for CPU-bound tasks, understanding and using threads effectively can help in optimizing various real-world applications.





Advertisement