views:

339

answers:

5

While developing a Django app deployed on Apache mod_wsgi I found that in case of multithreading (Python threads; mod_wsgi processes=1 threads=8) Python won't use all available processors. With the multiprocessing approach (mod_wsgi processes=8 threads=1) all is fine and I can load my machine at full.

So the question: is this Python behavior normal? I doubt it because using 1 process with few threads is the default mod_wsgi approach.

The system is:

2xIntel Xeon 5XXX series (8 cores (16 with hyperthreading)) on FreeBSD 7.2 AMD64 and Python 2.6.4


Thanks all for answers. We all found that this behavior is normal because of GIL. Here is a good explanation: http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/ or stackoverflow GIL discussion: http://stackoverflow.com/questions/1294382/what-is-a-global-interpreter-lock-gil.

+4  A: 

Will Python use all processors in thread mode? No.

Python won't use all available processors; is this Python behavior normal? Yes, it's normal because of the GIL.

For a discussion see http://mail.python.org/pipermail/python-3000/2007-May/007414.html.

You may find that having a couple (or 4) of threads per core/process can still improve performance if there is some blocking, for example waiting for a response from the database would cause that process to block other connections otherwise.

gnibbler
the last suggestion you made can't improve performance over a non-blocking single threaded approach
nosklo
+1  A: 

I don't know if it is still the case, but there is a global lock in the Python interpreter, which prevents the use of all processor resources from a single interpreter, even when using multi threading. IIRC, the global lock has to do with I/O.

It seems you are watching the result of this lock, so, personally, I would use multiple processes with a single thread.

Adrien Plisson
+4  A: 
  1. Will python use all processors in thread mode? No.

  2. It this normal? Yes, this is normal. Python makes no effort to locate all your cores.

  3. "1 process with few threads is default mod_wsgi approach". But that's not optimal or even desirable. That's just a default. Don't read anything into it.

If you want to use all your computer's resources, make the OS handle it. Use processes.

The distinction between multi-processing and multi-threading is hard to measure for the most part. Using processes or threads barely matters. It's usually simpler to use processes, since there's trivial OS support for this.

Bottom Line

Use multiple processes, that allows the OS (and Apache) to make as much use as possible of the system.

Threads share a limited set of I/O resources for the Process they're part of, and web page serving is I/O bound. Processes have independent I/O resources and will more easily max out your processor.

S.Lott
see also: http://docs.python.org/library/multiprocessing.html
exhuma
+1  A: 

Yes. Python is not really multi-threaded. Instead, there is a global lock and each thread gets to execute a few operations in turn. This makes it much more simple to write MT applications in Python since there can't be any problems with stale caches, etc.

So one Python process can only ever occupy a single CPU. To fully utilize a multi-core system, you must run several Python processes.

Aaron Digulla
+2  A: 

There is still hope. The GIL is only an implementation artifact of the C Python implementation that you download from python.org. Jython and IronPython are two other implementations of Python, and they have no GIL, so you may have better threading results with one of them.

Paul McGuire