enumМногие приходят в Rust из Go или Erlang и думают, что
async запускает легковесный поток (горутину). Забудьте. Асинхронный Rust работает совершенно иначе - он не аллоцирует стек под каждую задачу.Когда вы пишете
async fn, компилятор превращает вашу функцию в конечный автомат (State Machine).Смотрим код:
async fn fetch_data() {
let req = build_request();
let resp = send(req).await; // <-- Точка остановки 1
process(resp).await; // <-- Точка остановки 2
}
Под капотом LLVM генерирует невидимый
enum, который хранит локальные переменные между вызовами .await:
// Примерно так это видит компилятор:
enum FetchDataStateMachine {
Start,
WaitSend { req: Request }, // Храним локальные переменные
WaitProcess { resp: Response },
Done,
}
Когда рантайм вызывает метод
poll() у этой Future:1. Выполняется кусок кода до первого
.await.2. Состояние переключается (в
WaitSend).3. Управление возвращается обратно в рантайм! (Никакого блокирования потока).
Почему это круто? Такой
enum весит считанные байты. Вы можете создать миллион таких Future на обычном ноутбуке, и они займут всего пару десятков мегабайт оперативки. Никакая ОС не позволит вам создать миллион настоящих потоков.#rust #async #under_the_hood #future
👉 @rust_lib