[关闭]
@john-lee 2021-01-03T05:03:27.000000Z 字数 1522 阅读 715

有栈协程(Stackful Coroutines)

Boost.Asio


spawn()函数是运行有栈协程的高级包装器。它基于Boost.Coroutine库。spawn()函数使程序能够以同步方式实现异步逻辑,如下例所示:

  1. boost::asio::spawn(my_strand, do_echo);
  2. // ...
  3. void do_echo(boost::asio::yield_context yield)
  4. {
  5. try
  6. {
  7. char data[128];
  8. for (;;)
  9. {
  10. std::size_t length =
  11. my_socket.async_read_some(
  12. boost::asio::buffer(data), yield);
  13. boost::asio::async_write(my_socket,
  14. boost::asio::buffer(data, length), yield);
  15. }
  16. }
  17. catch (std::exception& e)
  18. {
  19. // ...
  20. }
  21. }

spawn()的第一个参数可以是strandio_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)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注