Python Program on Lock in Multithreaing using Thread Class Inheritance

Python course with 57 real-time projects - Learn Python

Entering the practical side of Python, we move on to the second part of our journey, exploring multithreading with locks. Now, our focus shifts to using Thread class inheritance for implementing locks, presenting an alternative method for coordinating thread execution. As we continue, our goal is to make the integration of locks with thread classes easy to understand, showcasing their role in making multithreading effective in Python.

Topic Explanation:

In the world of handling multiple tasks simultaneously, locks play a crucial role in managing shared stuff and keeping the order of how things happen. Thread class inheritance offers an object-oriented approach, allowing us to encapsulate the thread and lock functionalities within a custom class. This method enhances code modularity, making it easier to manage and understand the intricacies of concurrent programming. Through the inheritance of Thread class attributes, we seamlessly integrate lock mechanisms, ensuring thread-safe access to critical sections of our code.

Furthermore, as we explore the practical implementation, it becomes evident that the integration of locks through Thread class inheritance provides a more structured and reusable approach to multithreading. The encapsulation of threads and locks within a custom class facilitates clearer code organization. This approach not only enhances code readability but also fosters a more intuitive understanding of the relationship and contributes to efficient and maintainable multithreading practices.

Prerequisites:

Basic proficiency in Python programming.

  • Familiarity with the fundamentals of multithreading in Python.
  • Understanding the concept of shared resources in concurrent programming.
  • Awareness of the role of locks in preventing conflicts among threads.
  • Basic knowledge of object-oriented programming concepts.

Code With Comments:

# Importing necessary libraries
from threading import *
import time

# Creating a lock instance
l = Lock()

# Defining a class to encapsulate the printing of multiplication tables
class MyTable:
    def printtable(self, n):
        # Acquiring the lock to ensure exclusive access to shared resources
        l.acquire()
        for i in range(1, 11):
            # Printing the product of the number and the iteration
            print(n * i)
            # Introducing a delay to simulate a real-world scenario
            time.sleep(1)
        # Releasing the lock after completing the task
        l.release()

# Defining a custom thread class that inherits from Thread
class MyThread1(Thread):
    def run(self) -> None:
        # Creating an instance of MyTable
        M1 = MyTable()
        # Calling the printtable method with the argument 5
        M1.printtable(5)

# Defining another custom thread class that inherits from Thread
class MyThread2(Thread):
    def run(self) -> None:
        # Creating another instance of MyTable
        M1 = MyTable()
        # Calling the printtable method with the argument 7
        M1.printtable(7)

# Creating instances of the custom thread classes
My1 = MyThread1()
My2 = MyThread2()

# Starting the threads
My1.start()
My2.start()

Output:
5 10 15 20 25 30 35 40 45 50 7 14 21 28 35 42 49 56 63 70

Code Explanation:

Importing Libraries:

  • from threading import *: Importing the Thread class and other threading-related functions from the threading module.

Creating a Lock:

  • l = Lock(): Creating a lock instance using the Lock class.

Defining MyTable Class:

  • class MyTable: …: Creating a class to encapsulate the printing of multiplication tables.

Acquiring Lock:

  • l.acquire(): Acquiring the lock before entering the critical section to prevent concurrent access to shared resources.

Printing Table:

  • print(n * i): Printing the product of the number and the iteration.

Introducing Delay:

  • time.sleep(1): Introducing a 1-second delay to simulate a scenario where threads perform tasks with varying durations.

Releasing Lock:

  • l.release(): Releasing the lock after completing the critical section.

Defining MyThread1 Class:

  • class MyThread1(Thread): …: Creating a custom thread class that inherits from Thread.

Creating MyTable Instance:

  • M1 = MyTable(): Creating an instance of the MyTable class within the MyThread1 run method.

Starting Thread MyThread1:

  • My1.start(): Starting the MyThread1 thread.

Defining MyThread2 Class:

  • class MyThread2(Thread): …: Creating another custom thread class that inherits from Thread.

Creating Another MyTable Instance:

  • M1 = MyTable(): Creating another instance of the MyTable class within the MyThread2 run method.

Starting Thread MyThread2:

  • My2.start(): Starting the MyThread2 thread.

Conclusion:

Wrapping up our hands-on journey in Python, our exploration of multithreading with locks using Thread class inheritance reveals a useful and flexible method. This structured approach smoothly integrates threads and locks into custom classes, making the code more organized and flexible. As we navigate through this practical aspect of Python, the integration of locks through Thread class inheritance emerges as a potent strategy, amplifying the efficiency and maintainability of concurrent programming endeavors.

Did we exceed your expectations?
If Yes, share your valuable feedback on Google

follow dataflair on YouTube

Leave a Reply

Your email address will not be published. Required fields are marked *