Корутины C++ изнутри
Вопрос
Объясните, как устроены корутины в C++20: что делает компилятор, что такое promise_type и awaitable, и где их применяют.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Функция с co_await/co_yield/co_return становится корутиной
Кадр корутины в куче (с возможной оптимизацией HALO), coroutine_handle
promise_type управляет созданием, initial/final_suspend, результатом и исключениями
Awaitable: await_ready, await_suspend, await_resume
Бесстековые: приостановка только в самой корутине
Применение: генераторы, асинхронный ввод-вывод, std::generator в C++23
Что могут спросить следом
- Чем корутины отличаются от потоков?
- Как избежать висячих ссылок в параметрах корутины?
Разбор
Функция становится корутиной, если в ней есть co_await, co_yield или co_return. Компилятор переписывает её в машину состояний: локальные переменные и номер точки возобновления хранятся в кадре корутины, который по умолчанию выделяется в куче (оптимизатор может убрать аллокацию). Управлять ею можно через std::coroutine_handle. Поведение определяет promise_type из возвращаемого типа: он создаёт объект-результат, решает, приостановиться ли в начале и в конце (initial_suspend, final_suspend), принимает значения из co_yield и co_return и необработанные исключения. co_await expr работает с awaitable-объектом: await_ready говорит, можно ли не засыпать, await_suspend получает handle и решает, кто и когда нас возобновит, например планировщик ввода-вывода, await_resume возвращает результат. Корутины бесстековые, поэтому они лёгкие, но приостановиться можно только в самой корутине. Сами по себе они не дают параллелизма. Применяют для генераторов, в C++23 есть std::generator, и для асинхронного кода без колбэков. Главная ловушка: параметры по ссылке и захваты лямбд должны пережить корутину, которая может продолжиться позже.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.