In this article we will discuss how to create a thread in python by extending a class or by calling a member function of a class.
Python provides a threading module to manage threads. To use that we need to import this module i.e.
import threading
Now Python’s threading module provides a Thread class to create and manage threads. We can either extend this class to create a Thread or directly create Thread class object and pass member function of other class. Let’s see both techniques in detail,
Extend Thread class to create Threads
Suppose we have a class FileLoaderThread, which simulates the functionality of a file loader and it’s run() method sleeps for around 5 seconds. We can create this class by extending Thread class provided by the threading module i.e.
# A class that extends the Thread class class FileLoaderThread(Thread):
Now all the functionality of Thread class will be inherited to our FileLoaderThread class.
Thread class has a run() method that is invoked whenever we start the thread by calling start() function. Also, run() function in Thread class calls the callable entity (e.g. function) passed in target argument to execute that function in thread. But in our derived class we can override the run() function to our custom implementation like this,
# A class that extends the Thread class class FileLoaderThread(Thread): def __init__(self, fileName, encryptionType): # Call the Thread class's init function Thread.__init__(self) self.fileName = fileName self.encryptionType = encryptionType # Override the run() function of Thread class def run(self): print('Started loading contents from file : ', self.fileName) print('Encryption Type : ', self.encryptionType) for i in range(5): print('Loading ... ') time.sleep(1) print('Finished loading contents from file : ', self.fileName)
In class FileLoaderThread’s constructor (__init__() ) we have called the base class (Thread) __init__() function without any arguments and stored the passed arguments in it’s member variables. Also, we have overloaded the run() function and that will do some sleeping and when completes in around 5 seconds.
Frequently Asked:
Now as our class FileLoaderThread extends the Thread class has all it’s power, so we can create a thread by creating the object of this class i.e.
# Create an object of Thread th = FileLoaderThread('users.csv','ABC')
Also, we can call the start() function on it to start the thread and join() function to wait for it’s exit i.e.
# start the thread th.start() # print some logs in main thread for i in range(5): print('Hi from Main Function') time.sleep(1) # wait for thread to finish th.join()
It will basically create a new thread amd executes the run() function of class FileLoaderThread in parallel to main() function. Therefore output of the above code is as follows,
Started loading contents from file : users.csv Encryption Type : ABC Hi from Main Function Loading ... Loading ... Hi from Main Function Loading ... Hi from Main Function Loading ... Hi from Main Function Hi from Main Function Loading ... Finished loading contents from file : users.csv
Main function calls the join() on FileLoaderThread class object to wait for thread to finish. It’s because when main thread exists application exists without waiting for other threads. So, it better to wait for other threads to finish by calling join() on their object before returning from main thread.
Complete example is as follows,
from threading import Thread import time # A class that extends the Thread class class FileLoaderThread(Thread): def __init__(self, fileName, encryptionType): # Call the Thread class's init function Thread.__init__(self) self.fileName = fileName self.encryptionType = encryptionType # Override the run(0 function of Thread class def run(self): print('Started loading contents from file : ', self.fileName) print('Encryption Type : ', self.encryptionType) for i in range(5): print('Loading ... ') time.sleep(1) print('Finished loading contents from file : ', self.fileName) def main(): # Create an object of Thread th = FileLoaderThread('users.csv','ABC') # start the thread th.start() # print some logs in main thread for i in range(5): print('Hi from Main Function') time.sleep(1) # wait for thread to finish th.join() if __name__ == '__main__': main()
Output:
Started loading contents from file : users.csv Encryption Type : ABC Hi from Main Function Loading ... Loading ... Hi from Main Function Loading ... Hi from Main Function Loading ... Hi from Main Function Hi from Main Function Loading ... Finished loading contents from file : users.csv
Create a Thread from a member function of a class
Suppose we have a class FileLoader i.e.
class FileLoader(): def __init__(self): pass ''' A dummy function that prints some logs and sleeps in a loop/ takes approx 5 seconds to finish. ''' def loadContents(self, fileName, encryptionType): print('Started loading contents from file : ', fileName) print('Encryption Type : ', encryptionType) for i in range(5): print('Loading ... ') time.sleep(1) print('Finished loading contents from file : ', fileName)
Now we want to create a thread that executes the loadContents() member function of this class. For that first of all create an object of this class and then pass the member function along with object to the target argument of Thread class constructor while creating object i.e.
# Create an object of class FileLoader fileLoader = FileLoader() # Create a thread using member function of class FileLoader th = threading.Thread(target=fileLoader.loadContents, args=('users.csv','ABC', ))
Now both main() function and loadContents() member function of class FileLoader will run in parallel. So, the output of the above code is
Started loading contents from file : users.csv Encryption Type : ABC Hi from Main Function Loading ... Loading ... Hi from Main Function Loading ... Hi from Main Function Loading ... Hi from Main Function Hi from Main Function Loading ... Finished loading contents from file : users.csv
Both main thread and our new thread will run in parallel and in end main thread will wait for other thread to finish by calling join() function on it’s object.
Complete example is as follows,
import threading import time class FileLoader(): def __init__(self): pass ''' A dummy function that prints some logs and sleeps in a loop/ takes approx 5 seconds to finish. ''' def loadContents(self, fileName, encryptionType): print('Started loading contents from file : ', fileName) print('Encryption Type : ', encryptionType) for i in range(5): print('Loading ... ') time.sleep(1) print('Finished loading contents from file : ', fileName) def main(): # Create an object of class FileLoader fileLoader = FileLoader() # Create a thread using member function of class FileLoader th = threading.Thread(target=fileLoader.loadContents, args=('users.csv','ABC', )) # Start a thread th.start() # Print some logs in main thread for i in range(5): print('Hi from Main Function') time.sleep(1) # Wait for thread to exit th.join() if __name__ == '__main__': main()
Output
Started loading contents from file : Hi from Main Function users.csv Encryption Type : ABC Loading ... Loading ... Hi from Main Function Hi from Main Function Loading ... Hi from Main Function Loading ... Hi from Main Function Loading ... Finished loading contents from file : users.csv
Important Point about Outputs:
In above examples both main thread and our new thread are running in parallel and print messages on the console in parallel. Therefore order of outputs may vary from above outputs because console is a shared resource used by 2 threads in parallel. In future articles we will discuss how to synchronize a single resource between threads.