What does the GIL actually prevent, and how do you decide between threads, processes, and asyncio?
The Python GIL serializes CPython bytecode execution, but threads still help I/O-bound work; choose processes for pure Python CPU work and asyncio for many concurrent waits.
Answer
Short answer
The GIL prevents multiple threads in one CPython interpreter from running Python bytecode at the same time. Use threads for blocking I/O, processes for pure-Python CPU work, and asyncio when you need to coordinate many waiting operations.
Mention threading where it changes the risk, the owner, or the next check. A useful threading point should make the answer more testable, not merely longer. Tie threading back to the scenario so the interviewer can see why it matters here.
Was this answer helpful?
Likely follow-ups
- If the GIL serialises bytecode, why does a pure-Python CPU-bound function still get slower when you add threads?
- How would you call a blocking library from inside an asyncio event loop without stalling it?
- Why is a race condition still possible on `counter += 1` even with the GIL held?
- When would you reach for a C extension or a subinterpreter instead of multiprocessing?
Related questions
- Two processes share a memory region and both write to it. What do you need besides the memory, and what happens if one of them dies while holding the lock?hardAlso on concurrency5 min
- How would you design a thread-safe component, and why is adding synchronized to every method not a design?hardAlso on concurrency7 min
- You run ten coroutines concurrently and one of them raises. What happens to the other nine?hardAlso on asyncio5 min
- An operation in this code takes two locks and it deadlocks every few weeks. How would you design the locking so that cannot happen?hardAlso on concurrency6 min