user855
user855

Reputation: 19918

Does python3 asyncio use a work stealing scheduler like Rust Tokio?

Does Python 3 asyncio use a work-stealing scheduler like Rust Tokio? What's the behavior of the default scheduler? Is it documented somewhere?

Upvotes: 4

Views: 641

Answers (1)

user4815162342
user4815162342

Reputation: 154886

"Work-stealing" is an implementation strategy for multi-threaded executors. In this strategy each executor thread adds spawned tasks to a thread-local queue, and executes tasks off that queue. Only when the local queue is empty does an executor "steal" a task from another thread's queue. This provides great thread locality for balanced workloads while dynamically adapting to imbalanced ones.

Python asyncio's executor (event loop) is single-threaded, so it's by definition not work-stealing. The behavior of the asyncio event loop wrt threads is documented (among other places) in the Concurrency and Multithreading section of the documentation.

As for the algorithm used for scheduling, it's intentionally unspecified, but the stdlib implementation uses:

  • a deque to store callbacks that are ready to run (those scheduled with call_soon() or create_task()) as well as those associated with file descriptors that are ready to read/write, and
  • a binary heap to store callbacks scheduled for a particular time ordered by the absolute time when they're supposed to fire. This covers callbacks scheduled by loop.call_after() and loop.call_at(), but also continuation of coroutines suspended by asyncio.sleep(), which internally uses loop.call_at().

At each loop iteration the loop waits for something to happen on file descriptors associated with coroutines and sets the timeout to interrupt the sleep at the nearest time-based callback, in case nothing interesting happens before that. It proceeds to call the ready callbacks and the timeouts scheduled to run at the current or earlier time. This is repeated until the event loop is instructed to stop.

Upvotes: 7

Related Questions