Multithreaded Programming in Python

Neha Kumawat

a year ago

Python is a very interesting programming language. It provides us the facilities of multithreaded programming. Running several threads is similar to running several different programs concurrently and it providesthe following benefits to the user−
·        Multiple threads within a process share the same data space with the main thread and can therefore share information or communicate with each other more easily than if they were separate processes.
·        Threads sometimes called light-weight processes and they do not require much memory overhead; they are cheaper than process 
Python
Python

What is thread?

A thread is a separate flow of execution which means that your program will have two things happening at same time. It consists of a beginning, an execution sequence, and a conclusion. It has an instruction pointer that keeps track of where within its context it is currently running.
·        It can be interrupted in the middle of execution or pre-empted.
·        It can temporarily be put on hold this is also known as sleepingwhile other threads are running which is called yielding.

How to Start a New Thread

Python provides a thread module which is to start a thread. To spawn another thread, we need to call the below mention method which is available in python thread module.
thread.start_new_thread ( function, args[, kwargs] )
This method is used to enabled a fast and efficient way to create new threads in both Linux and Windows operating system.
It returns immediately and the child thread starts and calls function with the passed list of args. When the function returns, the thread get terminated.
Here, args is a tuple of arguments which is usedas an empty tuple to call the function without passing any arguments. kwargs is an optional dictionary of keyword arguments.
Let’s see an example
import thread as th
import time
# Defining a function for the thread
def print_time( threadName, delay):
    count = 0
    while count < 5:
time.sleep(delay)
        count += 1
        print "%s: %s" % ( threadName, time.ctime(time.time()) )
# Creating two threads as follows
try:
th.start_new_thread( print_time, ("Thread-1", 2, ) )
th.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
    print"Error occured : unable to start thread, please try again"
while 1:
    pass
When I run the above code, we will get the following output. Note: If you run this code maybe you will get the output.
Thread-1: FriAug 21 15:42:17 2020
Thread-1: Fri Aug 21 15:42:19 2020
Thread-2: Fri Aug 21 15:42:19 2020
Thread-1: Fri Aug 21 15:42:21 2020
Thread-2: Fri Aug 21 15:42:23 2020
Thread-1: Fri Aug 21 15:42:23 2020
Thread-1: Fri Aug 21 15:42:25 2020
Thread-2: Fri Aug 21 15:42:27 2020
Thread-2: Fri Aug 21 15:42:31 2020
Thread-2: Fri Aug 21 15:42:35 2020
Mainly thread module is very effective for low-level threading, but the thread module is very limited compared to the newer threading module for new and higher version of python.

The new Module: Threading 

Python does not support thread module in its old version. So, it provides the newer threading module included with Python 2.4 which is much more powerful, high-level support for threads than the thread module.
The new threading module exposes all the methods of the thread module and provides some additional methods such as −
·        threading.activeCount() –It returns the number of thread objects that are active.
·        threading.currentThread() –it returns the number of thread objects in the caller's thread control.
·        threading.enumerate() –it returns a list of all thread objects that are currently active.
In addition to the methods, the threading module has the Thread class that implements threading. The methods provided by the Thread class are as follows −
·        run() − The run() method is the entry point for a thread.
·        start() − The start() method starts a thread by calling the run method.
·        join([time]) − The join() waits for threads to terminate.
·        isAlive() − The isAlive() method checks whether a thread is still executing.
·        getName() − The getName() method returns the name of a thread.
·        setName() − The setName() method sets the name of a thread.

How to create thread Using Threading Module?

If you want to create a new thread using the threading module, you have to follow the below mentioned steps −
·        First, you have defined a new subclass of the Thread class.
·        Then you have overridden the __init__ (self [, args]) method to add additional arguments.
·        Later, override the run (self [,args]) method to implement what the thread should do when it get started.
Once you have created the new Thread subclass, you can create an instance of it and then start a new thread by invoking the start (), which in turn calls run () method.
Let’s see an example for it.
import threading
import time
exitFlag = 0
class my_Thread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
self.threadID = threadID
        self.name = name
self.counter = counter
    def run(self):
        print("Starting " + self.name)
print_time(self.name, 5, self.counter)
        print("Exiting " + self.name)
def print_time(threadName, counter, delay):
    while counter:
        if exitFlag:
threadName.exit()
time.sleep(delay)
        print("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1
# Create new threads
thread1 = my_Thread(1, "Thread-1", 1)
thread2 = my_Thread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
print("Exiting Main Thread")
When I run the above code, I received the following output.
Starting Thread-1
Starting Thread-2Exiting Main Thread
Thread-1: Fri Aug 21 13:21:27 2020
Thread-2: Fri Aug 21 13:21:28 2020
Thread-1: Fri Aug 21 13:21:28 2020
Thread-1: Fri Aug 21 13:21:29 2020
Thread-2: Fri Aug 21 13:21:30 2020
Thread-1: Fri Aug 21 13:21:30 2020
Thread-1: Fri Aug 21 13:21:31 2020
Exiting Thread-1
Thread-2: Fri Aug 21 13:21:32 2020
Thread-2: Fri Aug 21 13:21:34 2020
Thread-2: Fri Aug 21 13:21:36 2020
Exiting Thread-2

How to Synchronize the Threads?

Python threading module provide a simple-to-implement locking mechanism that allows you to synchronize the threads. Here, a new lock is created by calling the Lock () method, which returns the new lock.
The acquire(blocking) method of the new lock object is then used to force the threads to run synchronously. There is an optional blocking parameter which help you to enablesto control whether the thread waits to acquire the lock.
If you setblocking to 0, the thread returns immediately with a 0 value if the lock cannot be acquired and with a 1 if the lock was acquired. If blocking is set to 1, the thread blocks and wait for the lock to be released.
The release () method of the new lock object is used to release the lock when it is no longer required.
Let’s take an example:
import threading
import time
class my_Thread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
self.threadID = threadID
        self.name = name
self.counter = counter
    def run(self):
        print("Starting " + self.name)
        # Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
        # Free lock to release next thread
threadLock.release()
def print_time(threadName, delay, counter):
    while counter:
time.sleep(delay)
        print("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1
threadLock = threading.Lock()
threads = []
# Create new threads
thread1 = my_Thread(1, "Thread-1", 1)
thread2 = my_Thread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
# Add threads to thread list
threads.append(thread1)
threads.append(thread2)
# Wait for all threads to complete
for t in threads:
t.join()
print("Exiting Main Thread")
If we run the above code, the following results is obtained
Starting Thread-1Starting Thread-2
Thread-2: Fri Aug 21 13:32:57 2020
Thread-2: Fri Aug 21 13:32:59 2020
Thread-2: Fri Aug 21 13:33:01 2020
Thread-1: Fri Aug 21 13:33:02 2020
Thread-1: Fri Aug 21 13:33:03 2020
Thread-1: Fri Aug 21 13:33:04 2020
Exiting Main Thread

How to set Multithreaded Priority Queue?

There is another module known as Queue module which allows you to create a new queue object that can hold a specific number of items. Below are some of the following methods to control the Queue −
·        get() − The get() removes and returns an item from the queue.
·        put() − The put adds item to a queue.
·        qsize() − The qsize() returns the number of items that are currently in the queue.
·        empty() − The empty( ) returns true if queue is empty; otherwise, false.
·        full() − the full() returns true if queue is full; otherwise, false.
Let’s see an example for it.
#import libraries
import queue
import threading
import time
exitFlag = 0
#creating class
class my_Thread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
self.threadID = threadID
        self.name = name
self.q = q
    def run(self):
        print("Starting " + self.name)
process_data(self.name, self.q)
        print("Exiting " + self.name)
def process_data(threadName, q):
    while not exitFlag:
queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
queueLock.release()
            print("%s processing %s" % (threadName, data))
        else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for t_Name in threadList:
    thread = my_Thread(threadID, t_Name, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
    pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print("Exiting Main Thread")
When we run the above code, we get the following output.
Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-3 processing OneThread-2 processing Two
Thread-1 processing Three
Thread-2 processing Four
Thread-3 processing Five
Exiting Thread-2Exiting Thread-3Exiting Thread-1
Exiting Main Thread

I hope after reading this article, finally, you came to know about HowMultithreaded Programming can be done in Python, how you can Synchronize the Threads and how to set Multithreaded Priority Queue in python.

For more blogs/courses on data science, machine learning, artificial intelligence and new technologies do visit us at InsideAIML.
Thanks for reading…

Submit Review

We're Online!

Chat now for any query