In CPython, the Global Interpreter Lock (GIL) is a mutex that allows only one thread to execute Python bytecode at a time in a single process.
Why it exists
- Simplifies memory management (especially reference counting).
- Makes C extension integration safer historically.
Practical impact
- CPU-bound multi-threading does not get true parallel speedup on multiple cores for pure Python bytecode.
- I/O-bound threads can still help: the GIL is released around many blocking I/O operations, so threads can overlap waits.
- For CPU parallelism, prefer
multiprocessing, process pools, native extensions that release the GIL, or alternative runtimes.
import threading
counter = 0
def bump(n):
global counter
for _ in range(n):
counter += 1 # not atomic; still needs locks for correctness
threads = [threading.Thread(target=bump, args=(100_000,)) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print(counter) # often not 400_000 without a LockInterview nuance: The GIL is a CPython implementation detail, not part of the Python language spec. Also distinguish "GIL prevents parallel bytecode" from "threads are useless" (they are useful for I/O).