The global interpreter lock (GIL) is a CPython mutual-exclusion mechanism that prevents one process from executing more than one Python bytecode instruction at a time. Multiple threads may exist, but only one thread executes Python code at once, even on a multicore machine. section 1.5
The limitation matters most for CPU-bound Python code. Threads can share a process’s memory, but they generally cannot run CPU-intensive Python instructions in parallel. Separate processes each have their own GIL, allowing multiprocessing to execute bytecode concurrently. section 1.4.2 section 1.5
CPython’s reference-counting memory management helps explain why the GIL exists: unsynchronized thread access to shared Python objects can produce race conditions and unexpected states. The GIL addresses execution safety within the interpreter, but shared-state coordination remains a concurrency concern. section 1.5 section 7.6
The GIL is released during I/O because low-level system calls occur outside the Python runtime. Threads can therefore overlap network or other blocking I/O, producing concurrency without parallel execution of Python code. asyncio uses the same property with one thread and multiple coroutines; it does not bypass the GIL. section 1.5.1 section 1.5.2
CPU-bound versus I/O-bound work
Two recursive Fibonacci calculations took about 65.15 seconds sequentially and about 66.11 seconds with threads, showing no CPU-bound speedup. By contrast, two threaded requests for example.com took about 0.0977 seconds versus 0.2306 seconds synchronously, because the threads overlapped I/O. section 1.5 section 1.5.1




