Sign up ×

I have a Python program that spawns many threads, runs 4 at a time, and each performs an expensive operation. Pseudocode:

for object in list:
    t = Thread(target=process, args=(object))
    # if fewer than 4 threads are currently running, t.start(). Otherwise, add t to queue

But when the program is run, Activity Monitor in OS X shows that 1 of the 4 logical cores is at 100% and the others are at nearly 0. Obviously I can't force the OS to do anything but I've never had to pay attention to performance in multi-threaded code like this before so I was wondering if I'm just missing or misunderstanding something.


share|improve this question

3 Answers 3

up vote 21 down vote accepted

Note that in many cases (and virtually all cases where your "expensive operation" is a calculation implemented in Python), multiple threads will not actually run concurrently due to Python's Global Interpreter Lock (GIL).


CPython uses what’s called “operating system” threads under the covers, which is to say each time a request to make a new thread is made, the interpreter actually calls into the operating system’s libraries and kernel to generate a new thread. This is the same as Java, for example. So in memory you really do have multiple threads and normally the operating system controls which thread is scheduled to run. On a multiple processor machine, this means you could have many threads spread across multiple processors, all happily chugging away doing work.


See the Global Interpreter Lock section of Jesse Noller's post for more details.

To get around this problem, check out Python's multiprocessing module.

multiple processes (with judicious use of IPC) are[...] a much better approach to writing apps for multi-CPU boxes than threads.

-- Guido van Rossum (creator of Python)

share|improve this answer
Thank you very much for the detailed answer- multiprocessing was it. For anyone else interested, multiprocessing.Pool also took care of the problem of limiting the number of active worker threads. – Rob Lourens Dec 22 '10 at 6:11
What do I do on Windows then? Multiprocessing sucks on Windows because the child processes don't inherit an object from the memory of the parent process. I want to do a multi-threaded map of a function onto a large list. – John Peter Thompson Garcés Apr 2 '13 at 16:54

Python has a Global Interpreter Lock, which can prevent threads of interpreted code from being processed concurrently.

For ways to get around this, try the multiprocessing module, as advised here:

Does running separate python processes avoid the GIL?

share|improve this answer

AFAIK, in CPython the Global Interpreter Lock means that there can't be more than one block of Python code being run at any one time. Although this does not really affect anything in a single processor/single-core machine, on a mulitcore machine it means you have effectively only one thread running at any one time - causing all the other core to be idle.

share|improve this answer

Your Answer


