@john-lee
2021-01-03T05:47:38.000000Z
字数 1785
阅读 1027
Boost.Asio
对 Coroutines TS 的支持通过可等待类模板、use_awaitable完成令牌和 co_spawn)函数提供。这些工具允许程序以同步方式实现异步逻辑,并结合关键字实现,如下例所示:co_await
通过awaitable
类模板、use_awaitable
完成令牌和co_spawn()
函数提供对协程技术规范的支持。这些功能允许程序以同步的方式结合co_await
关键字实现异步逻辑,如下例所示:
boost::asio::co_spawn(executor, echo(std::move(socket)), boost::asio::detached);
// ...
boost::asio::awaitable<void> echo(tcp::socket socket)
{
try
{
char data[1024];
for (;;)
{
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
co_await async_write(socket, boost::asio::buffer(data, n), boost::asio::use_awaitable);
}
}
catch (std::exception& e)
{
std::printf("echo Exception: %s\n", e.what());
}
}
co_spawn()
的第一个参数是一个执行器,它确定允许执行的协程的上下文。例如,服务端的每个客户端对象可能由多个协程组成;服务端的每个客户端对象可能由多个对象组成。它们都应该在同一strand
上运行,这样就不需要显式同步。
第二个参数是waitiable<R>
,它是协程入口点函数的结果,在上面的示例中是调用echo
的结果。(或者,此参数可以是返回waitiable<R>
的函数对象)模板参数R
是协程生成的返回值的类型。在上面的示例中,协程返回void
。
第三个参数是一个完成标记,co_spawn()
使用它生成一个签名为void(std::exception_ptr, R)
的完成处理程序。一旦完成,这个完成处理程序就会被协程的结果调用。在上面的示例中,我们传递了一个完成令牌类型boost::asio::detached
,它用于显式忽略异步操作的结果。
在本例中,协程的主体在echo
函数中实现。当use_awaitable
完成标记被传递给异步操作时,操作的启动函数返回一个awaitable
,可以与co_await
关键字一起使用:
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
其中,异步操作的处理程序签名的格式为:
void handler(boost::system::error_code ec, result_type result);
co_await
表达式的结果类型是result_type
。在上面的async_read_some
示例中,这是size_t
。如果异步操作失败,error_code
将转换为system_error
异常并抛出。
处理程序签名的格式为:
void handler(boost::system::error_code ec);
co_await
表达式产生一个void
结果。如上所述,错误作为system_error
异常传递回协程。
co_spawn,detached,redirect_error,awaitable, use_awaitable_t, use_awaitable, this_coro::executor,协程技术规范的例子,有栈协程,无栈协程。
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)