Simple Multithreading in Python


Creating threads is very easy in Python. The following is the example that I use to demonstrate the multithreading in Python.

#!/usr/bin/env python

import threading
import time

# lock to synchronize the message printing
lock = threading.Lock()

def tprint(msg):
    global lock
    lock.acquire()
    print msg
    lock.release()

# first step, extend the Thread object
class Test(threading.Thread):

    threadID = 0

    # second step, override the constructor
    def __init__(self, ID):
        self.threadID = ID
        # make sure you invoke the parent constructor
        threading.Thread.__init__(self)

    # third step, implement the run(), which will be invoked
    # at the notation: thread.start()
    def run(self):
        tprint ("ThreadID = " + str(self.threadID))
        print "You will see the difference", self.threadID
        time.sleep(self.threadID)
        tprint("Thread " + str(self.threadID) + " finishes.")

if __name__ == "__main__":
    threads = []

    # create threads and put them in the list
    for i in range(1, 3):
        t = Test(i)
        threads.append(t)

    # start each thread roughly at the same time
    for i in threads:
        i.start()

    for i in threads:
        if i.isAlive():
            tprint(i.getName() + " is alive.")
        else:
            tprint(i.getName() + " is dead.")
            
    tprint('activeCount = ' + str(threading.activeCount()))
    tprint('currentThread = ' + str(threading.currentThread()))

    # synchronize all threads
    for i in threads:
        i.join()

    print threads[0].threadID
    print threads[1].threadID
    tprint("Main Thread")

The above example will output the following.

ThreadID = 1</div>
You will see the difference ThreadID = 2
You will see the difference Thread-1 is alive.
Thread-2 is alive.
activeCount = 4
currentThread = <_MainThread(MainThread, started 2032)>
Thread 1 finishes.
Thread 2 finishes.
1
2
Main Thread

First of all, you need to import the threading module. This module provides the class Thread, which you should use as a parent class. The next would be to override the constructor __init__(self). Please note that you can add parameters to your own constructor as long as you remember to call the super constructor (parental constructor in Thread)

The run() method is an abstract super method which you need to implement in your own thread class. This method will be invoked when the notation thread.start() is used.

The print function is not thread-safe, that is why you will see messages interleaving each other from different threads if you do not use synchronization techniques. The threading module provides a Lock class which you can easily use to synchronize the resources. In the given example, the tprint function is defined which replaced the built-in print. It uses a lock to ensure at the same time, only one printing is allowed. The acquire() method will allow threads to enter critical sections, for those threads that haven’t obtained the lock, they will be kept waiting until the release() method is invoked by the thread which obtained the lock in the first place.

The threadID as shown in the example, is thread-var, which means, each thread has an individual copy of the variable (not shared). This maybe different in other programming languages, e.g. in Delphi, you have to declare the thread variables using keyword ‘threadvar’ otherwise all the variables e.g. class attributes will be treated as the same memory locations by all threads. At the end of the given example, the thread IDs are printed, which shows that the class attributes defined do not share the same memory locations (not static) by different threads.

The threading module provides some additional methods:

threading.activeCount(): Returns the number of thread objects that are active.
threading.currentThread(): Returns the number of thread objects in the caller’s thread control.
threading.enumerate(): Returns a list of all thread objects that are currently active.
The example given is pretty straightforward, and I hope you will start loving Python.

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
696 words
Last Post: Constructor and Destructor in Python Classes
Next Post: A Recursive Full Permutation Algorithm in Python

The Permanent URL is: Simple Multithreading in Python

Leave a Reply