Перейти к содержанию

Начало урока

Корутины (C++20)

Функции, которые умеют приостанавливаться, запоминать своё место и продолжаться позже

Главная идея: Обычная функция выполняется сверху вниз и возвращает управление ровно один раз. Корутина способна приостановиться посреди работы, вернуть управление вызвавшему её коду и позже продолжиться ровно с той точки, где остановилась, при этом все её локальные переменные сохраняются. C++20 добавляет три ключевых слова — co_await, co_yield, co_return — которые превращают обычную на вид функцию в такую приостанавливаемую машину состояний. Эта единственная возможность лежит в основе двух совсем разных инструментов: ленивых генераторов (выдают значения по одному по требованию) и асинхронного кода без колбэков (пишем последовательный код в стиле await, который не блокирует поток).

К концу вы сможете:
  • точно сказать, что делает функцию корутиной и что делают три ключевых слова co_;
  • объяснить кадр корутины, promise_type и coroutine_handle;
  • читать самописный Generator, который лениво выдаёт значения через co_yield;
  • увидеть, как co_await заменяет цепочки колбэков прямолинейным асинхронным кодом;
  • назвать честные компромиссы: кадры в куче, скромная библиотечная поддержка в C++20 и ловушки времени жизни.

1. Что делает функцию корутиной

Корутину не объявляют особым ключевым словом в сигнатуре. Функция становится корутиной, если её тело использует хотя бы одно из трёх ключевых слов:

  • co_await expr — возможно приостановиться, пока expr не будет готово, затем продолжить (и, при желании, получить результат).
  • co_yield value — выдать одно значение вызывающему коду и приостановиться; эквивалент co_await promise.yield_value(value).
  • co_return value — завершить корутину, при желании передав итоговый результат.

Компилятор переписывает такую функцию в машину состояний. Поскольку управление может покидать тело и снова в него входить, локальные переменные не могут жить в обычном стеке вызовов (кадр стека исчезает в момент приостановки). Вместо этого они живут в кадре корутины: блоке памяти, обычно в куче, где хранятся параметры, локальные переменные и небольшой служебный объект — promise (обещание).

Ловушка в названии: promise_type корутины не имеет отношения к std::promise/std::future. Это точка настройки, с которой общается компилятор; напрямую вы её почти не трогаете — её предоставляет библиотечный тип.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя