Skip to content

Week 11 - The GIL, Free-Threaded Python, and the Concurrency Model

11.1 Conceptual Core

  • The Global Interpreter Lock serializes Python bytecode execution. It does not serialize C extensions that release it (NumPy, PyTorch, time.sleep, most I/O). This is why "Python is single-threaded" is wrong on the parts that matter.
  • CPU-bound, pure-Python → multiprocessing or free-threaded build (PEP 703).
  • CPU-bound, native (NumPy/torch) → threads are fine; the GIL is released.
  • I/O-bound → asyncio (preferred) or threads.

11.2 Mechanical Detail

  • The GIL is a single mutex around the interpreter state. Released on I/O syscalls and on every ~5ms timeslice (sys.setswitchinterval).
  • Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS in C extensions: how NumPy/torch escape.
  • PEP 703 free-threaded build (3.13 experimental, 3.14 stable target): per-object locking, biased reference counting, deferred reference counting for immortal objects. Trade-off: ~10–20% single-threaded slowdown, true parallel threads. Build with --disable-gil or use python3.13t.
  • PEP 684 per-interpreter GIL: subinterpreters with their own GIL, interpreters module (PEP 734, 3.13+). Promising for embedded multitenancy.
  • threading.Lock, RLock, Semaphore, Condition, Event, Barrier. The atomicity guarantees of CPython on dict/list ops are implementation details, not language-level - under free-threaded these change. Always use a lock if you require atomicity.

11.3 Lab - "GIL Awareness"

  1. Compute primes up to 1M three ways: (a) single thread, (b) threading with 8 threads, (c) multiprocessing with 8 procs. Bench all three on stock CPython.
  2. Run (b) on python3.13t (free-threaded). Compare.
  3. Replace the prime-test inner loop with a NumPy expression. Re-run (b) on stock CPython. Note the GIL-release effect.
  4. Capture py-spy record flame graphs for each. Identify GIL contention visually.

11.4 Idiomatic & Linter Drill

  • Enable ruff ASYNC. Catch time.sleep inside async def, blocking I/O inside async, etc.

11.5 Production Hardening Slice

  • Add py-spy continuous profiling to your CI'd service. On every PR, attach a flame graph artifact.

Comments