Использовали ли вы Boost coroutines?
Что проверяют
Знаете ли вы, что под этим названием в Boost скрывается несколько разных библиотек, и отличаете ли stackful-корутины от корутин C++20. Следом обычно спрашивают, как это связано с Boost.Asio и что вы выбрали бы в новом проекте.
Как отвечать
Вопрос про опыт, так что опирайтесь на свой проект: какая задача, какая библиотека, что получилось с памятью и читаемостью. Нужны свои детали. Если не использовали, скажите прямо и покажите, что ориентируетесь в теме:
- Boost.Coroutine: первая версия, объявлена устаревшей, в новом коде её не берут;
- Boost.Coroutine2: асимметричные stackful-корутины поверх Boost.Context, пара
coroutine<T>::pull_typeиpush_type. Удобна для генераторов и ленивых последовательностей. Сама по себе ничего не делает асинхронным, это просто переключение контекста; boost::asio::spawnсyield_context: stackful-корутины для сетевого кода. Асинхронная операция принимаетyieldкак completion token, и код читается линейно, без колбэков;- C++20 в Asio:
co_spawn,awaitable<T>иuse_awaitableповерхco_await. Это stackless-корутины, сейчас основной путь; - Boost.Cobalt: отдельная библиотека на корутинах C++20 с задачами, генераторами и каналами.
Главное различие стоит объяснить. Stackful-корутине выделяется свой стек, поэтому приостановиться она может из любой вложенной функции, но за каждую платите памятью под стек и риском переполнить слишком маленький стек. Stackless-корутина хранит только кадр в куче и приостанавливается лишь в точках co_await. Зато она дешевле, таких корутин можно держать очень много, а компилятор иногда вообще убирает аллокацию кадра.
Где спотыкаются
Говорят, что корутины сами делают код асинхронным и быстрым. Без планировщика вроде io_context они просто передают управление друг другу в одном потоке.
Передают в корутину ссылки на локальные объекты вызывающего кода. После первой приостановки объект уже уничтожен, остаётся висячая ссылка.
Забывают про потоки: если io_context крутят несколько потоков, корутина может продолжиться на другом, и thread_local или незащищённое общее состояние ломаются. В Asio для этого есть strand.