3 ms·
How is async/await implemented under the hood?
by coolThingsFirst 3y ago
How is async/await implemented under the hood?
- lmm 3y agoGenerally via continuations. An async function is transformed to continuation-passing style, await calls with the current continuation, and then you have a runtime that at its simplest is just, like, a queue of tasks and has special-cased primitives for doing things like async I/O where you suspend, and it just pulls tasks off the queue and runs them, and when one task suspends it stores the continuation and runs the next one.
- politelemon 3y agoDoes that runtime run the tasks across multiple cores?
- amaranth 3y agoIn Rust the answer is "it depends". Since the runtime is not provided by the language you can have implementations that are a single thread, thread-per-task, a thread pool, or whatever other setup you can think of. Tokio at least offers a single threaded version and a thread pool version.
- simonask 3y agoAsync/await in Rust is famously not based on continuations, at least not in any traditional sense, where a block of code is passed to a reactor system to be invoked whenever an operation completes. Instead it is based on "wakers", which are objects associated with a task, and can be used to notify the task's executor that the task is ready to make progress. It is then the job of an executor resume the task. So there is an extra layer of indirection (conceptually). There are pros and cons, but in essence the system trades a check on resume (often redundant) for the need to make a heap allocation and/or type erasure at each await point. (It's possible to avoid the latter in continuation-based implementations, like C++ coroutines, but it's pretty hard.)
- deleted 3y ago[deleted]
- LtWorf 3y agopoll()