@john-lee
2021-01-03T05:03:27.000000Z
字数 1522
阅读 833
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)




