Асинхронные задачи и типы awaiter
Составляйте асинхронные задачи с пользовательскими типами awaiter и promise.
«Асинхронные задачи и типы awaiter» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Асинхронные корутины
Асинхронная задача приостанавливается во время ввода-вывода и возобновляет выполнение после завершения операции. Сочетайте co_await с асинхронными интерфейсами, чтобы писать асинхронный код без обратных вызовов.
Эскиз типа Task
Task оборачивает асинхронную корутину. Он поддерживает co_await для построения цепочек.
template <typename T>
struct Task {
struct promise_type;
std::coroutine_handle<promise_type> handle;
// ...
};Механика co_await
Когда компилятор встречает co_await expr, он ожидает, что expr будет ожидаемым объектом. У ожидаемого объекта есть три метода:
await_ready()— значение false для приостановки и true, чтобы её пропуститьawait_suspend(handle)— действия во время приостановкиawait_resume()— значение, передаваемое вызывающему коду
Пример ожидаемого объекта: Sleep
Ожидаемый объект, который планирует возобновление выполнения после задержки.
struct Sleep {
std::chrono::milliseconds duration;
bool await_ready() const { return false; }
void await_suspend(std::coroutine_handle<> h) {
std::thread([h, this] {
std::this_thread::sleep_for(duration);
h.resume();
}).detach();
}
void await_resume() {}
};
Task<void> example() {
co_await Sleep{500ms};
std::cout << "after 500ms";
}Ожидаемый объект для HTTP
Библиотеки предоставляют ожидаемые объекты для HTTP-запросов, таймеров и файлового ввода-вывода. Объединяйте их так же, как обычные синхронные вызовы.
Task<std::string> fetch() {
auto data = co_await http_get("/api/data");
co_return data;
}Объединение задач
Ожидание одной задачи внутри другой связывает их в цепочку. Внешняя задача приостанавливается до завершения внутренней.
Task<int> outer() {
int x = co_await inner_a();
int y = co_await inner_b();
co_return x + y;
}Параллельные задачи
Для параллельной асинхронной работы запускайте задачи, не ожидая немедленного завершения каждой из них, а затем дождитесь их всех.
Task<int> sum_tasks() {
auto a = inner_a();
auto b = inner_b();
int x = co_await a;
int y = co_await b;
co_return x + y;
}Распространение исключений
Исключения, выброшенные внутри асинхронной задачи, могут быть сохранены в unhandled_exception объекта promise и повторно выброшены на стороне ожидающего кода.
Отмена
Стандартная библиотека пока не предоставляет примитив отмены. Библиотеки, такие как cppcoro и boost.cobalt, реализуют собственные варианты — обычно с помощью токенов отмены или источников остановки.
Интеграция с Boost.Asio
Asio изначально поддерживает корутины. Используйте co_await с операциями async_read, async_write и подобными. На сегодняшний день это самый удобный способ асинхронного ввода-вывода в C++.
Производительность
Возобновление корутины значительно дешевле переключения потоков. Компилятор часто встраивает части автомата состояний. Выполните профилирование, чтобы убедиться, что цепочка ожидаемых объектов компилируется эффективно.
Дальнейшие направления
В C++23 добавлен std::generator и внесены другие улучшения. В C++26 может появиться std::execution с моделью отправителей и получателей — более универсальная асинхронная среда, взаимодействующая с корутинами.
Быстрая проверка
Какие три метода должен иметь тип ожидаемого объекта?
Итоги
Асинхронные задачи сочетают co_await с ожидаемыми объектами, позволяя писать асинхронный код без обратных вызовов. Ожидаемые объекты содержат await_ready, await_suspend и await_resume. Библиотеки, такие как cppcoro и Asio, предоставляют готовые типы задач и ожидаемых объектов.
Часто задаваемые вопросы
Урок «Асинхронные задачи и типы awaiter» бесплатный?
Да — полный текст урока «Асинхронные задачи и типы awaiter» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Асинхронные задачи и типы awaiter»?
Составляйте асинхронные задачи с пользовательскими типами awaiter и promise. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Асинхронные задачи и типы awaiter»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Концепции сопрограмм: co_await, co_yield, co_return
- Реализация простого генератора
- Асинхронные задачи и типы awaiter
- Выделение памяти для кадра сопрограммы