Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

coroutine

Boost , Boost.Asio , Reference

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Обеспечивает поддержку реализации безстековых корутин.

class coroutine
Member Functions

Имя

Описание

Корутина

Построение корутина в его первоначальном состоянии.

— [ребенок]

Возвращается истинно, если корутина — дитя вилки.

является

Возвращается истинно, если корутина достигла своего конечного состояния.

является родителем

Возвращается истинно, если корутина является родителем вилки.

Класс<coroutine>может использоваться для реализации безстековых корутин. Сам класс используется для хранения текущего состояния корутина.

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

class session : coroutine
{
  ...
};

или в качестве члена данных:

class session
{
  ...
  coroutine coro_;
};

или даже связан в качестве аргумента функции с использованием лямбда или<bind()>. Важно то, что приложение сохраняет копию объекта до тех пор, пока корутина должна быть сохранена.

Pseudo-keywords

Корутин используется в сочетании с определенными «псевдоключевыми словами», которые реализуются как макросы. Эти макросы определяются файлом заголовка:

#include <boost/asio/yield.hpp>

и могут быть не определены следующим образом:

#include <boost/asio/unyield.hpp>

вернуться

Макро<reenter>используется для определения тела корутина. Для этого требуется один аргумент: указатель или ссылка на корутинный объект. Например, если базовый класс является корутинным объектом, вы можете написать:

reenter (this)
{
  ... coroutine body ...
}

Если вы являетесь участником данных или другой переменной, вы можете написать:

reenter (coro_)
{
  ... coroutine body ...
}

Когда<reenter>выполняется во время выполнения, управление переходит к месту последнего<yield>или<fork>.

Корутинный орган также может быть единым утверждением, таким как:

reenter (this) for (;;)
{
  ...
}

Ограничение:Макрос<reenter>реализуется с помощью переключателя. Это означает, что вы должны быть осторожны при использовании локальных переменных в организме. Локальная переменная не допускается в положении, когда повторное вхождение в корутин может обойти определение переменной.

доходностьзаявление

Эта форма ключевого слова<yield>часто используется с асинхронными операциями:

yield socket_->async_read_some(buffer(*buffer_), *this);

Это делится на четыре логических шага:

  • <yield>сохраняет текущее состояние корутина.
  • Заявление инициирует асинхронную операцию.
  • Пункт резюме определяется сразу после заявления.
  • Контроль переносится на конец корутинного тела.

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

Утверждение также может быть составным, и это позволяет нам определить локальные переменные с ограниченным охватом:

yield
{
  mutable_buffers_1 b = buffer(*buffer_);
  socket_->async_read_some(b, *this);
}

доходностьвыражение;

Эта форма<yield>часто используется в генераторах или корутинных парсерах. Например, объект функции:

struct interleave : coroutine
{
  istream& is1;
  istream& is2;
  char operator()(char c)
  {
    reenter (this) for (;;)
    {
      yield return is1.get();
      yield return is2.get();
    }
  }
};

определяет тривиальный корутин, который переплетает символы из двух входных потоков.

Этот тип<yield>делится на три логических шага:

  • <yield>сохраняет текущее состояние корутина.
  • Точка резюме определяется сразу после запятой.
  • Значение выражения возвращается из функции.

доходность;

Эта форма<yield>эквивалентна следующим шагам:

  • <yield>сохраняет текущее состояние корутина.
  • Точка резюме определяется сразу после запятой.
  • Контроль переносится на конец корутинного тела.

Эта форма может применяться, когда корутины используются для совместной резьбы, а планирование явно управляется. Например:

struct task : coroutine
{
  ...
  void operator()()
  {
    reenter (this)
    {
      while (... not finished ...)
      {
        ... do something ...
        yield;
        ... do some more ...
        yield;
      }
    }
  }
  ...
};
...
task t1, t2;
for (;;)
{
  t1();
  t2();
}

разрыв доходности;

Окончательная форма<yield>используется для явного прекращения корутина. Эта форма состоит из двух этапов:

  • <yield>устанавливает корутинное состояние для обозначения прекращения.
  • Контроль переносится на конец корутинного тела.

После того, как они были прекращены, призывы к<is_complete()>возвращению истинны, и корутина не может быть возвращена.

Обратите внимание, что корутин также может быть неявно прекращен, если корутинное тело выходит без выхода, например, путем возврата, броска или бега к концу тела.

вилказаявление

Псевдоключевое слово<fork>используется при «разветвлении» корутина, т.е. разбиении его на две (или более) копии. Одно из применений<fork>находится на сервере, где для обработки каждого клиентского соединения создается новый корутин:

reenter (this)
{
  do
  {
    socket_.reset(new tcp::socket(io_service_));
    yield acceptor->async_accept(*socket_, *this);
    fork server(*this)();
  } while (is_parent());
  ... client-specific handling follows ...
}

Логические этапы, участвующие в<fork>:

  • <fork>сохраняет текущее состояние корутина.
  • Заявление создает копию кодеина и либо выполняет его немедленно, либо планирует его для последующего исполнения.
  • Точка резюме определяется сразу после запятой.
  • Для «родителя» контроль сразу же продолжается со следующей строки.

Функции<is_parent()>и<is_child()>могут использоваться для различения между родителем и ребенком. Вы будете использовать эти функции для изменения последующего потока управления.

Обратите внимание, что<fork>не делает сам разветвление. В обязанности приложения входит создание клона корутина и его вызов. Клон можно вызвать немедленно, как указано выше, или запланировать на отсроченное исполнение, используя что-то вроде<io_service::post()>.

Alternate macro names

При желании приложение может использовать макро-имена, которые следуют более типичному соглашению об именах, а не псевдоключевым словам. Это:

  • <BOOST_ASIO_CORO_REENTER>вместо<reenter>
  • <BOOST_ASIO_CORO_YIELD>вместо<yield>
  • <BOOST_ASIO_CORO_FORK>вместо<fork>
Requirements

Заголовок:<boost/asio/coroutine.hpp>

Удобный заголовок:<boost/asio.hpp>


PrevUpHomeNext

Статья coroutine раздела Boost.Asio Reference может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Reference ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 08:39:03/0.0055348873138428/0