# Core Python Applications Programming: Multithreaded Programming

• Print
This chapter is from the book

## 4.6. Comparing Single vs. Multithreaded Execution

The mtfacfib.py script, presented in Example 4-8 compares execution of the recursive Fibonacci, factorial, and summation functions. This script runs all three functions in a single-threaded manner. It then performs the same task by using threads to illustrate one of the advantages of having a threading environment.

#### Example 4-8. Fibonacci, Factorial, Summation (mtfacfib.py)

In this MT application, we execute three separate recursive functions—first in a single-threaded fashion, followed by the alternative with multiple threads.

```1    #!/usr/bin/env python
2
4    from time import ctime, sleep
5
6    def fib(x):
7        sleep(0.005)
8        if x < 2: return 1
9        return (fib(x-2) + fib(x-1))
10
11   def fac(x):
12       sleep(0.1)
13       if x < 2: return 1
14       return (x * fac(x-1))
15
16   def sum(x):
17       sleep(0.1)
18       if x < 2: return 1
19       return (x + sum(x-1))
20
21   funcs = [fib, fac, sum]
22   n = 12
23
24   def main():
25       nfuncs = range(len(funcs))
26
27       print '*** SINGLE THREAD'
28       for i in nfuncs:
29           print 'starting', funcs[i].__name__, 'at:', 30               ctime()
31           print funcs[i](n)
32           print funcs[i].__name__, 'finished at:', 33               ctime()
34
35       print '\n*** MULTIPLE THREADS'
36       threads = []
37       for i in nfuncs:
38           t = MyThread(funcs[i], (n,),
39               funcs[i].__name__)
41
42       for i in nfuncs:
44
45       for i in nfuncs:
48
49       print 'all DONE'
50
51   if __name__ == '__main__':
52       main()```

Running in single-threaded mode simply involves calling the functions one at a time and displaying the corresponding results right after the function call.

When running in multithreaded mode, we do not display the result right away. Because we want to keep our MyThread class as general as possible (being able to execute callables that do and do not produce output), we wait until the end to call the getResult() method to finally show you the return values of each function call.

Because these functions execute so quickly (well, maybe except for the Fibonacci function), you will notice that we had to add calls to sleep() to each function to slow things down so that we can see how threading can improve performance, if indeed the actual work had varying execution times—you certainly wouldn’t pad your work with calls to sleep(). Anyway, here is the output:

```\$ mtfacfib.py
starting fib at: Wed Nov 16 18:52:20 2011
233
fib finished at: Wed Nov 16 18:52:24 2011
starting fac at: Wed Nov 16 18:52:24 2011
479001600
fac finished at: Wed Nov 16 18:52:26 2011
starting sum at: Wed Nov 16 18:52:26 2011
78
sum finished at: Wed Nov 16 18:52:27 2011

starting fib at: Wed Nov 16 18:52:27 2011
starting fac at: Wed Nov 16 18:52:27 2011
starting sum at: Wed Nov 16 18:52:27 2011
fac finished at: Wed Nov 16 18:52:28 2011
sum finished at: Wed Nov 16 18:52:28 2011
fib finished at: Wed Nov 16 18:52:31 2011
233
479001600
78
all DONE```