Export to GitHub

pyloadtools - CodeTutorialMultiThreading.wiki


This is part of: "Web Performance Testing - Building Web Performance/Load Testing Tools in Python 3.0"

Go Back To Web Performance Testing Tutorial Home: http://code.google.com/p/pyloadtools/


Python 3.0 - Multithreading

In this section, we learn to use multiple in preparation to create a tool that can send concurrent requests to a web server.

A thread is short for a "thread of execution". Threads are a way for a program to split itself into several simultaneously running tasks. This lets you run multiple operations concurrently within a single process.


Note About Python Threads: GIL - Native Threads Versus Green Threads

"Not all threads are created equal. There are two main ways of implementing threads. Native threads are implemented by the kernel. Green threads are implemented at the interpreter or virtual machine level. Native threads are heavier because context switching at the kernel level is comparatively expensive. However, green threads can't take advantage of multiple CPUs. That is because from the kernel's perspective, the whole VM is running as a single native thread.

Python was earlier than many of the other interpreters at the time to support native threads. However, there's a catch -- the global interpreter lock (the 'GIL'). Supporting native threads in a thread-safe way is hard. This problem is compounded by the need to interface with non-thread-safe C extensions. The GIL is a lock that is used to protect all the critical sections in Python. Hence, even if you have multiple CPUs, only one thread may be doing 'pythony' things at a time.

Python threads are terrible for multi-CPU and multi-Core concurrency if you are CPU-bound on Python code. If you have four CPUs, and you're trying to do some heavy data crunching using Python code, Python threads won't help. Three of the four CPUs will spend most of their time blocked, waiting to acquire the GIL."

- Shannon Behrens, Concurrency and Python


Simple Threading Example - thread module

The thread module provides a way to work with multiple threads.

Here is a very simple example of using the thread module to spawn 3 threads:

``` import _thread

def hello(num): print('hello from thread %s\n' % num)

_thread.start_new_thread(hello, (0,)) _thread.start_new_thread(hello, (1,)) _thread.start_new_thread(hello, (2,)) ```

This will create 3 threads. Each one will run the hello() function, print a message, and then exit.

The output looks like this:

hello from thread 0 hello from thread 1 hello from thread 2


Simple Threading Example - threading module

The threading module provides a way to work with multiple threads. You subclass its Thread class and create a run() method. You then instantiate an object and call a start() method. When this happens, the object's run() method gets executed in a new thread. The run() method contains the code you wish to be executed when the thread is spawned.

Here is a very simple example of using the threading module to spawn 3 threads:

``` from threading import Thread

class MyThread(Thread): def run(self): print('hello from thread %s' % self.name)

for i in range(3): my_thread = MyThread() my_thread.name = i my_thread.start() ```

This will create 3 threads. Each one will print a message once and then exit.

The output looks like this:

hello from thread 0 hello from thread 1 hello from thread 2


Multithreaded Example

Here is another example of using the threading module to spawn multiple threads. This approach is more object oriented and the threads run until the main program is killed.

```

!/usr/bin/env python

Corey Goldberg, 2009 (corey@goldb.org)

#

Multithreaded framework

import time from threading import Thread

THREADS = 3

def main(): manager = ThreadManager() manager.start(THREADS)

class ThreadManager: def init(self): pass

def start(self, threads):
    thread_refs = []
    for i in range(threads):
        t = MyThread(i)
        t.daemon = True
        print('starting thread %i' % i)
        t.start()
    for t in thread_refs:
        t.join()

class MyThread(Thread): def init(self, i): Thread.init(self) self.i = i

def run(self):
    while True:
        print('hello from thread # %i' % self.i) 
        time.sleep(.25)            

if name == 'main': main() ```


(c) 2008-2009 Corey Goldberg - corey@goldb.org - www.goldb.org