Chapter 2 of 6
Event loops, threads and processes
Run one workload three ways — on an event loop, on a thread pool and on a process pool — and record throughput alongside CPU. Two facts account for everything you measure: an event loop is a single thread that only overlaps waiting, and the global interpreter lock means one CPython process executes one bytecode stream at a time, so pure-Python CPU work stays pinned near a single core however many threads you add.
Async and concurrency in Python — read the current version at https://daviddominguez.dev/learn/en/async-and-concurrency-in-python/event-loops-threads-and-processes