[Python] GIL (Global Interpreter Lock)

Rex Chiang
2 min readApr 8, 2023

In CPython, the GIL (Global Interpreter Lock) is a mutex that protects access to Python objects, preventing multiple threads from executing Python bytecodes at once. The GIL prevents race conditions and ensures thread safety. In short, this mutex is necessary mainly because CPython’s memory management is not thread-safe.

Cooperative Multitasking

When receive some requests which are blocking operations, it can release GIL voluntarily, and start processing another request, instead of waiting for a response.

Preemptive Multitasking

Python text is compiled into a simpler binary format called bytecode, then the Python interpreter reads the bytecode and executes the instructions in it one by one. While the interpreter steps through your bytecode it release GIL involuntarily, and start processing another request, instead of waiting for a response.

Thread safety

The thread can lose the GIL at any moment if the operation is not atomic, so it need to ensure the safety for thread.

  • Atomic operation

There is no opportunity for other threads to have the GIL if the operation is atomic, because it is a single bytecode.

l = [2, 4, 3, 1]

def func():
l.sort()
# ByteCode

0 LOAD_GLOBAL 0 (lst)
2 LOAD_METHOD 1 (sort)
4 CALL_METHOD 0
  • Nonatomic operation

The GIL might be released involuntarily during nonatomic operation, because it is not a single bytecode.

n = 0

def func():
n += 1
# ByteCode

0 LOAD_GLOBAL 0 (n)
2 LOAD_CONST 1 (1)
4 INPLACE_ADD
6 STORE_FAST 0 (n)

Despite the GIL, still need locks to protect shared mutable state.

n = 0
lock = threading.Lock()

def func():
with lock:
n += 1

--

--