What the GIL is, and why
The Global Interpreter Lock is a single mutex inside CPython that serialises access to interpreter state. Only one OS thread executes Python bytecode at any moment. Threads exist; they take turns. The lock is held by the interpreter loop and released around blocking syscalls, long-running C extensions, and at the periodic switch interval (5 ms default, sys.getswitchinterval(), unchanged from Python 3.2 through 3.14).
The reason: CPython manages memory by reference counting. Every PyObject has a refcount field that increments on assignment and decrements on scope exit. Without a global lock, every increment and decrement on shared objects would need an atomic operation. The GIL is the design choice to use one big lock instead of millions of small atomic ops — the trade is CPU-bound thread parallelism for refcount-update simplicity. The trade was made in CPython's early threading design (mid-1990s) and Python has lived with it ever since.