Каковы фактические правила для ожидания Final_suspend в сопрограммах C++?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Каковы фактические правила для ожидания Final_suspend в сопрограммах C++?

Сообщение Anonymous »

В сопрограммах C++ функция-член Final_suspend типа обещания может возвращать любой произвольный ожидаемый тип, хотя обычно это std::suspend_always, который оставляет ответственность за уничтожение сопрограммы на кого-то другого, или std: :suspend_never, который автоматически уничтожает сопрограмму. Последнее, по-видимому, является особым случаем, поскольку обычно не разрешается возобновлять сопрограмму, находящуюся в конечной точке приостановки. Однако в моем тестировании кажется, что это особое поведение не применяется единообразно.
Суть проблемы заключается в том, что функция-член awaitable await_suspend может иметь любой из трех разных возвращаемых значений. типы: если он возвращает void, сопрограмма остается приостановленной. Если он возвращает bool, сопрограмма возобновляется для false и остается приостановленной для true. Если он возвращает std::coroutine_handle, эта сопрограмма возобновляется.
Я протестировал поведение всех этих результатов с помощью возвращаемого значения Final_suspend , и все три MSVC, Clang и GCC сходятся в этом поведении для ожидаемого объекта, где await_ready всегда возвращает false:
  • Если Final_suspend().await_suspend(handle) возвращает void, сопрограмма остается приостановленной в конечной точке приостановки, как и ожидалось.
  • Если Final_suspend().await_suspend( handle) возвращает bool(true), в этом случае сопрограмма также остается приостановленной в конечной точке приостановки.
  • Если Final_suspend().await_suspend(handle) возвращает bool(false), что интересно, сопрограмма автоматически уничтожается, что видно по выполняемому деструктору типа обещания. Это соответствует поведению std::suspend_never и показывает, что решение может быть принято во время выполнения. Также интересно отметить, что await_resume вызывается и перед уничтожением сопрограммы, даже если ее результат отбрасывается.
  • If Final_suspend().await_suspend(handle) возвращает дескриптор другой сопрограммы, эта сопрограмма возобновляется, как и ожидалось, а текущая сопрограмма остается приостановленной в конечной точке приостановки.
  • Если Final_suspend().await_suspend(handle) возвращает задан тот же дескриптор, программа выходит из строя!
Результаты 1, 2 и 4 соответствуют ожиданиям. Результаты 3 и 5 интересуют меня больше всего - с определенной точки зрения можно подумать, что к ним будут относиться одинаково, поскольку в обоих случаях они пытаются «возобновить» завершенную сопрограмму, но только результат 3, кажется, получает специальную обработку. для автоматического уничтожения сопрограммы. Из-за этого немного неудобно решать это во время выполнения при возврате дескриптора сопрограммы, поскольку вместо этого вам придется вручную уничтожить сопрограмму, а затем вернуть дескриптор неактивной сопрограммы, что немного сложнее, чем просто возврат false для того же эффекта и может даже сделать некоторые варианты использования невозможными из-за необходимости возвращать дескриптор со стертым типом.
Мой вопрос в том, где именно эти конкретные результаты описаны или обязательны в Стандарт С++? Когда я смотрю, я не могу найти многого. Стандарт выглядит довольно кратким в описании поведения сопрограммы. Кажется, что особое поведение awaitable Final_suspend важно задокументировать, но я не могу его найти. Я могу найти заявление о том, что Final_suspend и использование его ожидаемого значения должно быть noException («не должно быть потенциально выбрасывающим»), но это все, что касается специальных правил. исходить из того, что я могу найти. Какой раздел мне не хватает? Почему возврат того же самого переданного дескриптора приводит к иному поведению, чем возврат false?

Подробнее здесь: https://stackoverflow.com/questions/783 ... coroutines
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»