Функция spawn()
представляет собой высокоуровневую обертку для выполнения сложенных корутин. Он основан на росте. Корутинная библиотека. Функция spawn()
позволяет программам реализовывать асинхронную логику синхронно, как показано в следующем примере:
boost::asio::spawn(my_strand, do_echo);
void do_echo(boost::asio::yield_context yield)
{
try
{
char data[128];
for (;;)
{
std::size_t length =
my_socket.async_read_some(
boost::asio::buffer(data), yield);
boost::asio::async_write(my_socket,
boost::asio::buffer(data, length), yield);
}
}
catch (std::exception& e)
{
}
}
Первым аргументом для spawn()
может быть strand
, io_service
или completion handler. Этот аргумент определяет контекст, в котором корутину разрешено выполнять. Например, объект каждого клиента сервера может состоять из нескольких корутин; все они должны работать на одной и той же strand
, чтобы не требовалась явная синхронизация.
Второй аргумент — это объект функции с подписью:
void coroutine(boost::asio::yield_context yield);
который определяет код, который должен быть запущен как часть корутина. Параметр yield
может быть передан асинхронной операции вместо обработчика завершения, как в:
std::size_t length =
my_socket.async_read_some(
boost::asio::buffer(data), yield);
Это запускает асинхронную операцию и приостанавливает корутин. Коротин будет возобновлен автоматически при завершении асинхронной операции.
Если подпись обработчика асинхронной операции имеет форму:
void handler(boost::system::error_code ec, result_type result);
функция инициации возвращает тип результата. В приведенном выше примере async_read_some
это size_t
. Если асинхронная операция не удается, error_code
преобразуется в исключение system_error
и выбрасывается.
Если подпись обработчика имеет форму:
void handler(boost::system::error_code ec);
функция инициации возвращает void
. Как указано выше, ошибка передается обратно в корутин в виде исключения system_error
.
Чтобы собрать error_code
из операции, вместо того, чтобы сделать исключение, связать выходную переменную с yield_context
следующим образом:
boost::system::error_code ec;
std::size_t length =
my_socket.async_read_some(
boost::asio::buffer(data), yield[ec]);
Примечание: если spawn()
используется с пользовательским обработчиком завершения типа Handler
, подпись объекта функции фактически:
void coroutine(boost::asio::basic_yield_context<Handler> yield);
spawn, yield_context, basic_yield_context, Spawn example (C++03), Spawn example (C++11), Stackless Coroutines.