03
May
07

Python: Fun with Threads

Most people will agree that threads are an important part of most useful software systems. They allow the computer to go off and work on something while the user continues to enjoy interaction with the rest of the system – In fact most GUI applications are a prime example of threading – The interface is running separate from the core of the application to ensure that if the application dies behind the scenes it doesn’t necessarily take the rest of the computer with it. (However some win32 applications would have us believe otherwise)

The problem with constructing threads, however, is usually the housekeeping that needs to go into the background. We need to think about the data interactions and decide what data needs to be encapsulated in mutual exclusive surroundings for safety. Then we need to design the thread(s) that will modify this data.

Suppose, however, that you just want to despatch very simple threads that will run a single function. Why bother doing that tedious work? Well, after a quick look at how standard python handles threading I thought of a neat way that one might create a generic thread handler to request functions to be done neatly in the background. This code was written with a vanilla installation of Python 2.4 on Windows XP. I don’t know enough about Python to write ‘OS specific’ code so it should work on most machines.
ALSO: Since python is a live interpreter all this code can simply be typed into the python shell.

The first step is to import the python threading library

import threading

Now Here’s a simple function:

def factorial( n ):
if n == 0:
return 1
else:
return n * factorial(n-1)

Very simply takes a number and returns the factorial. I realise that it’s not the most practical way to implement factorial but it’ll do for a demo. What I’m going to do now is write a thread class making use of pythons groovy function pointers:

class AsyncFunc(threading.Thread):
def __init__(self, func, n):
threading.Thread.__init__(self)
self.function, self.arg = func, n
def run(self):
self.result = self.function(self.arg)
print “result: “, self.result

Pay attention to the parameters in the class header – the class extends threading.Thread. This means that we want to call the constructor of the supserclass and this is done in the first line of __init__. (__init__ is just python’s fun way of implementing constructors). We create an instance of AsyncFunc giving it a function and an argument (I have only shown a demo for single argument functions – things like square, factorial, fibbonacci.) and these are stored as members in the class.

The run method is the sequence of execution that will happen when the process scheduler tells this class it can start working.In this case all we want to do is run our function with the argument given. This is a really, really, truly cool feature of python that I love – the self.function member is actually a link to the factorial function which we passed in as a parameter – you can’t do this in Java!!

At the end of run I’ve just told it to print the result to let us know it’s finished – in a real world scenario we may also pass a buffer address to the function so that we can get access to the result from our main process.

We are now ready to start using our threaded system and it’s as simple as this. first declare an instance of an AsyncFunc:

bgFactorial = AsyncFunc(factorial, 5)

and then pass it to the process scheduler:

bgFactorial.start()

In no time at all the result will be returned – but rest assured it happened in another thread. You can redefine your AsyncFunc with larger values and see that it takes longer but doesn’t disrupt your work.

Just for a laugh I added the following loop scenario – a word of caution though, you may either spawn more threads than the python system can comfortably handle, or you may exceed the maximum recursion depth (because the factorial definition is not great)

for i in range(1000):
temp = AsyncFunc(factorial, i)
temp.start()

I managed to grind my python session to a halt, but it’s all a bit of fun anyway.

Hopefully this has been a little insightful or interesting. I was trying to capture something similar to the Microthreading that can be used in Stackless python


1 Response to “Python: Fun with Threads”


  1. June 3, 2007 at 3:27 pm

    Perhaps pythons needs a better compiler !


Leave a Reply

You must login to post a comment.