Question 17 of 20 Intermediate Concept
What does the global interpreter lock mean for parallelizing a CPU-bound Python analysis?
Short answer
In the standard CPython build only one thread runs Python bytecode at a time, so threads do not speed up pure-Python number crunching. Use processes, or libraries such as NumPy that release the GIL inside compiled code. Free-threaded builds remove the lock but are still optional.
Why
The GIL is a lock in CPython that lets only one thread execute Python bytecode at once. It keeps the interpreter simple and safe, but a loop that scores 10,000 sequences in pure Python gets no faster with eight threads. Threads still help when the work waits on input and output, such as downloading files, because the GIL is released while waiting on input and output.
They also help when the heavy work happens inside compiled code that releases the lock, which the Python glossary notes for tasks such as compression and hashing, and which NumPy does for many low-level array operations, though not for object arrays. For pure-Python CPU work the usual answer is multiple processes, through multiprocessing or concurrent.futures.ProcessPoolExecutor, at the cost of copying data between processes. Python 3.13 introduced a free-threaded build without the GIL, and PEP 779 made it officially supported but still optional from Python 3.14.
It has some single-thread overhead, and importing a C extension not marked as safe can switch the GIL back on with a warning. Check sys._is_gil_enabled() rather than assuming. Before parallelizing anything, profile, because vectorizing the inner loop often gives a larger gain than any number of workers.
A strong answer covers
- One thread runs bytecode at a time in standard CPython
- Threads help for waiting on files and networks, and for GIL-releasing compiled code
- Processes parallelize pure-Python CPU work
- Free-threaded build is supported but optional since 3.14
- Profile and vectorize before parallelizing
Common mistakes
- Expecting a thread pool to speed up a pure-Python loop on a multi-core machine
- Assuming a free-threaded interpreter stays GIL-free after importing any extension module
The interviewer might ask next
What would you measure before choosing between processes, threads and vectorization for a slow scoring step?