Hello dear readers! welcome back to another section of our tutorial on Python. In this tutorial post, we are going to be discussing about Multithreading in Python.
Running serveral threads is like running many various programs at the same time, but with the following benefits -
Running serveral threads is like running many various programs at the same time, but with the following benefits -
- Multiple threads within a process do share the same data space with the main thread and can therefore share information or easily communicate with each other than if they were in separate processes.
- Threads at times called light-weight processes and they do not need much memory overhead; they are cheaper than processes.
RECOMMENDED POST: Python if Statement Tutorial with examples
A thread has a beginning, an execution sequence and also a conclusion. It has an instruction pointer that keeps track of where it is currently running within its context.
- It can be be interrupted.
- It can temporarily be placed on hold while other threads are running (this is called yielding).
Starting a New Thread
To start up a new thread, you need to call the following methods available in the thread module -
Syntax
Following is the syntax for starting a new thread and the needed methods -
thread.start_new_thread ( function, args[, kwargs] )
This method call enables a fast and efficient way to create new threads in both Windows and Linux.
RECOMMENDED: Python Strings Tutorial
The method call returns instantly and the child thread starts and calls function with the passed list of args. When the function returns, the thread terminates.
Here, args is a tuple of arguments; use an empty tuple to call a function without passing any arguments to it. Here kwargs is an optional dictionary of keyword arguments.
Here, args is a tuple of arguments; use an empty tuple to call a function without passing any arguments to it. Here kwargs is an optional dictionary of keyword arguments.
Example
The following below is a simple example -
#!/usr/bin/python import thread import time # Define 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()) ) # Create two threads as follows try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass
Output
When the above code is executed, it will produce the following result -
Thread-1: Mon Aug 31 15:42:17 2020 Thread-1: Mon Aug 31 15:42:19 2020 Thread-2: Mon Aug 31 15:42:19 2020 Thread-1: Mon Aug 31 15:42:21 2020 Thread-2: Mon Aug 31 15:42:23 2020 Thread-1: Mon Aug 31 15:42:23 2020 Thread-1: Mon Aug 31 15:42:25 2020 Thread-2: Mon Aug 31 15:42:27 2020 Thread-2: Mon Aug 31 15:42:31 2020 Thread-2: Mon Aug 31 15:42:35 2020
Although it is extremely effective for low-level threading, but the threading module is very limited compared to the new threading module.
RECOMMENDED: Complete List of Python Standard Exceptions
The Threading Functions
The newer threading functions included in the Python version 2.4 provides much more powerful, high-level support for threads than the threading module that was discussed above.
The threading module reveals all the the methods of the thread module as well as providing some additional methods.
The threading module reveals all the the methods of the thread module as well as providing some additional methods.
threading.activeCount()
This method returns the number of thread objects that are active.
threading.currentThread()
This method returns the number of thread objects in the caller's thread control.
threading.enumerate()
This function returns the list of all the thread objects currently active.
In addition to the above methods, the thread module has the Thread class that implements threading. Here are the methods provided by the Thread class -
- run() - This method is the entry point of a thread.
- start() - This method starts a thread by calling the run method
- join([time]) - This method waits for the threads to terminate.
- isAlive() - This function checks if a thread is still executing.
- getName() - This method returns the name of a thread.
- setName() - This function sets the name of a thread.
RECOMMENDED: Assertion in Python Programing
Creating Threads using Threading Module
To implement a new thread using the threading module, you have to do the following -
- Define a new subclass of the Thread class.
- Override __init__(self [, args]) method to add additional arguments.
- Finally, override the run(self [, args]) method to implement what should be done by the thread when started.
Once you are done creating the new Thread subclass, you can create an instance of it and then begin a new thread by calling the start() method, which in turn calls the run() method.
Example
The following below is a simple example -
#!/usr/bin/python import threading import time exitFlag = 0 class myThread (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 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() print "Exiting Main Thread"
Output
When the above code is executed, it will produce the following result -
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Mon Aug 31 09:10:03 2020 Thread-1: Mon Aug 31 09:10:04 2020 Thread-2: Mon Aug 31 09:10:04 2020 Thread-1: Mon Aug 31 09:10:05 2020 Thread-1: Mon Aug 31 09:10:06 2020 Thread-2: Mon Aug 31 09:10:06 2020 Thread-1: Mon Aug 31 09:10:07 2020 Exiting Thread-1 Thread-2: Mon Aug 31 09:10:08 2020 Thread-2: Mon Aug 31 09:10:10 2020 Thread-2: Mon Aug 31 09:10:12 2020 Exiting Thread-2
RECOMMENDED: A Guide to Python Exception Handling
Synchronizing Threads
The threading module provided with Python includes a simple-to-implement locking mechanism that allows you to synchronize threads. A new lock is created by calling the lock() method, which returns the new lock.
The acquire() Method
The acquire(blocking) method of the new lock object is used in forcing the threads to run synchronously. In this method, the blocking parameter is optional and it enables you to control whether the thread waits to acquire the lock.
If blocking parameter is set to 0, the thread returns immediately with a 0 value if the lock can not be acquired and with 1 if the lock was acquired. If blocking is set to 1, then the thread blocks and waits for the lock to be released.
If blocking parameter is set to 0, the thread returns immediately with a 0 value if the lock can not be acquired and with 1 if the lock was acquired. If blocking is set to 1, then the thread blocks and waits for the lock to be released.
The release() Method
The release function of the new lock object is utilized in releasing the lock whenever it is no longer required
Example
The following below is a simple example -
#!/usr/bin/python import threading import time class myThread (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 = myThread(1, "Thread-1", 1) thread2 = myThread(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"
Output
When the above code is executed, it will produce the following result -
Starting Thread-1 Starting Thread-2 Thread-1: Mon Aug 31 09:11:28 2020 Thread-1: Mon Aug 31 09:11:29 2020 Thread-1: Mon Aug 31 09:11:30 2020 Thread-2: Mon Aug 31 09:11:32 2020 Thread-2: Mon Aug 31 09:11:34 2020 Thread-2: Mon Aug 31 09:11:36 2020 Exiting Main Thread
RECOMMENDED POST: Network Programming in Python
Multithreaded Priority Queue
The Queue module allows you to create a new queue object that can hold a specific number of items. Following below are the methods to control the Queue -
- get() - The get() method removes and returns an item from the queue.
- put() - The put() method adds item to the queue.
- qsize() - The qsize() method returns the number of items currently in the queue.
- empty() - This function returns True if the queue is empty, else False.
- full() - The full() method returns True if queue is full, else False.
Example
#!/usr/bin/python import Queue import threading import time exitFlag = 0 class myThread (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 tName in threadList: thread = myThread(threadID, tName, 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"
Output
When the above code is executed, it will produce the following result -
Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-1 processing One Thread-2 processing Two Thread-3 processing Three Thread-1 processing Four Thread-2 processing Five Exiting Thread-3 Exiting Thread-1 Exiting Thread-2 Exiting Main Thread
RECOMMENDED: Sending Emails in Python using SMTP
Alright guys! This is where we are rounding up for this tutorial post. In our next tutorial, we are going to be discussing about the Python XML Processing.
Feel free to ask your questions where necessary and i will attend to them as soon as possible. If this tutorial was helpful to you, you can use the share button to share this tutorial.
Follow us on our various social media platforms to stay updated with our latest tutorials. You can also subscribe to our newsletter in order to get our tutorials delivered directly to your emails.
Thanks for reading and bye for now.
Feel free to ask your questions where necessary and i will attend to them as soon as possible. If this tutorial was helpful to you, you can use the share button to share this tutorial.
Follow us on our various social media platforms to stay updated with our latest tutorials. You can also subscribe to our newsletter in order to get our tutorials delivered directly to your emails.
Thanks for reading and bye for now.