@john-lee
2021-01-03T05:03:27.000000Z
字数 1522
阅读 715
Boost.Asio
spawn()
函数是运行有栈协程的高级包装器。它基于Boost.Coroutine库。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_context
或完成处理程序。此参数确定允许执行的协程的上下文。例如,服务器的每个客户机对象可能由多个协程组成;它们都应该在同一个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);
启动函数返回result_type
。在上面的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,生成示例 (C++03),生成示例 (C++11),无栈协程)。
Copyright © 2003-2020 Christopher M. Kohlhoff
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)