The Global Interpreter Lock (GIL)

Introduction

From David Beazley's 2010 presentation:

* As a few of you might know, C Python has a
  Global Interpreter Lock (GIL)

  >>> import that
  The Unwritten Rules of Python

  1. You do not talk about the GIL.
  2. You do NOT talk about the GIL.
  3. Don't even mention the GIL. No seriously.
  ...

* It limits thread performance

* Thus, a source of occasional "contention"

So you really want to know about the GIL

What is the GIL?

  • a lock on the python interpreter
    • only one thread has access to the python core
    • simplifies many low-level details (memory management, callouts to C extensions, etc.)

Why do we care?

  • only one python thread can run at the same time
  • gets bad when threads are cpu-bound
  • works OK when threads are io-bound

Thread Execution Model

../_images/gil_cooperative_threading.png

CPU-Bound Tasks

But what if we have no I/O to release the GIL?

A "check" occurs every 100 "ticks":

  • if other threads are waiting, switch to one of them
  • otherwise, continue with current thread

This sounds OK, but I sense a "but"

Thread switching works well on a single cpu, but breaks down on multi-cpu.

  • When thread A releases the GIL, it can immediately reacquire it before the other thread wakes up

    (remember, both threads have their own core, so they aren't waiting for each other)

  • On multicore, I/O operations may not block

    The OS can buffer the request using other cores, and have the data ready immediately.

    However, the GIL is always released on I/O.

Multi-core causes starvation and thrashing!

Some Plots

../_images/gil_multicore.png

So, what should we do?

If your program is not cpu-bound or super I/O intensive, don't worry about this and continue using threads.

Otherwise, think carefully whether the GIL will cause problems for you.

If needed, the sledgehammer called multiprocessing is available.