Какой исполнитель создает co_await boost::asio::this_coro::executor?

В документации boost::asio::this_coro::executor указано, что это

Ожидаемый объект, возвращающий исполнителя текущей сопрограммы.

Мне это кажется несколько расплывчатым, когда в игру вступают несколько Executors; Я предполагал, что co_await это обеспечит Executor, в котором в данный момент выполняется сопрограмма, т. е. я ожидал, что утверждение в этом фрагменте будет успешным:

boost::asio::io_context ioc;
auto io_ex = ioc.get_executor();

boost::asio::co_spawn(io_ex,
    [&]() -> boost::asio::awaitable<void> {
        
        auto switch_strand = boost::asio::make_strand(io_ex);
        co_await boost::asio::post(switch_strand, boost::asio::use_awaitable);
        assert(switch_strand == co_await boost::asio::this_coro::executor);
    },
    boost::asio::detached);

ioc.run();

Однако оказывается, что даже после перехода от post к switch_strand, io_ex == co_await boost::asio::this_coro::executor. Почему это происходит? Будет ли co_await boost::asio::this_coro::executor всегда создавать Executor сопрограмму, которая изначально была co_spawn включена, независимо от того, переключусь ли я на любую другую Executor внутри сопрограммы? Вызов post с switch_strand вообще «переключается на любую другую Executor внутри сопрограммы»?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Исполнитель является свойством сопрограммы. Вот почему вы можете запросить тип обещания awaitable, используя трансформируемый объект (this_coro::executor). Возможно, даже был сделан сознательный выбор дизайна, который выбрал

 auto ex = co_await this_coro::executor; // this syntax

над

 auto ex = co_await this_coro::executor(); // instead of this syntax

в отличие от других интерактивных преобразований.

Почему это происходит?

Так оно и было задумано. В большинстве случаев сопрограммы являются самоизменяющимися продолжениями. Продолжения являются обработчиками. Обработчики могут иметь связанных исполнителей. Когда вы co_spawn(ex, foo, ...) просите все эти продолжения привязать к ex.

См. также комментарии к коду

Будет ли co_await boost::asio::this_coro::executor всегда создавать Исполнителя, на котором изначально была создана сопрограмма

Да. См. также преобразование в коде

независимо от того, переключаюсь ли я на любого другого исполнителя внутри сопрограммы? Призыв к публикации с помощью switch_strand даже «переключается на любого другого исполнителя в сопрограмме»?

Да и нет:

  • Да, co_await post(bind_executor(x, deferred)); приведет к возобновлению работы сопрограммы при x.
  • Нет, это не изменяет внутренние свойства Attached_thread_ сопрограммы.

Спасибо, это прояснило ситуацию. Итак, насколько я понимаю ваш ответ, до тех пор, пока я явно не укажу bind_executor на boost::asio::use_awaitable (или boost::asio::deferred), co_await он возобновит выполнение сопрограмм («оригинальных») исполнителя, переданных co_spawn (он же co_await boost::asio::this_coro::executor), даже если он в данный момент выполняется на каком-то другом (явно связанном) исполнителе. Можете ли вы это подтвердить?

Reizo 15.06.2024 14:04

Да, я тоже это понимаю.

sehe 15.06.2024 14:06

Кстати. Я просто хочу отметить, что я уже знал оба места исходного кода, на которые вы ссылались, но все еще не мог самостоятельно ответить на свои вопросы. В частности, несмотря на то, что я просмотрел реализацию awaitable_frame_base::await_transform(this_coro::executor_t)‌​, я не смог сам подтвердить, что ее результат определенно был результатом, переданным исполнителем co_spawn. Хотя обычно я справляюсь с документацией и исходным кодом, сложность (и, возможно, запутывание) в Boost.Asio — это нечто иное.

Reizo 15.06.2024 14:13

Другие вопросы по теме

Похожие вопросы

В чем разница между decltype(type) и decltype(vector_of_type)?
Перемещение после копирования при присвоении результата условного оператора
Почему `std::integral_constant` имеет `::type`, который ссылается на себя?
Агрегатная инициализация, которая имеет инициализатор члена, когда значения инициализации меньше количества членов
Макросы LITTLE_ENDIAN, BIG_ENDIAN и BYTE_ORDER должны загрязнять мое глобальное пространство имен с помощью GCC?
Что происходит, когда сопрограмма возвращается в приостановленную сопрограмму?
Boost Asio: исполнители в сопрограммах C++20
Можно ли рассматривать reinterpret_cast как небезопасный обходной путь, когда динамический_cast недоступен?
Как предотвратить возникновение противоречивых ошибок в конфигурациях отладки и выпуска для «недоступного кода» и «не все пути возвращают значение»
Можно ли в Visual Studio Code автоматически переключаться на панель «Проблемы», когда при сборке возникают ошибки?