https://realpython.com/async-io-python/
Multiprocessing all the way!
Good article!
Synchronous code is like a single-lane road where cars (tasks) must travel one after another in perfect sequence. If one car stops for gas (waiting for I/O), every car behind it must stop too. While orderly and predictable, this creates massive traffic jams as tasks wait unnecessarily for others to complete before they can proceed.
Pure asynchronous code (with callbacks) is like dispatching multiple cars onto independent routes with no coordination. Cars move freely without waiting for each other, but they arrive at unpredictable times and following their progress becomes chaotic. It's efficient but creates a complex tangle of paths that becomes hard to maintain.
Async/await combines the best of both approaches with a multi-lane highway system. Cars follow clear, synchronous-looking routes (making code readable), but only wait at strategic "await" exit ramps when truly necessary. When a car needs data, it signals with "await", pulls off the highway temporarily, and other cars continue flowing past. Once its operation completes, it merges back into traffic and continues. This gives you the logical simplicity of synchronous code with the performance benefits of asynchronous execution - cars only wait at crossroads when they must, maximizing throughput while maintaining order.
The genius of async/await is that it lets developers write code that looks sequential while the runtime handles all the complex traffic management under the hood.
Instead of using a global lock ("red-cap"), Python objects have introduced a specialized reference counting system that distinguishes between "local" references (owned by a single thread) and "shared" references (accessed by multiple threads).
In that way enabling to remove GIL in the long run, now starting with making it optional.
quentinp•7h ago