c – boost :: asio :: spawn有什么作用?

我无法形成关于控制流如何与spawn发生的精神图景.

>当我调用spawn(io_service,my_coroutine)时,它是否会向io_service队列添加一个新的处理程序来包装对my_coroutine的调用
>当在协同程序中我调用异步函数传递我的yield_context时,是否挂起协同程序直到异步操作完成?

void my_coroutine(yield_context yield)
{
  ...
  async_foo(params ...,yield);
  ...   // control comes here only once the async_foo operation completes
}

我不明白的是我们如何避免等待.假设my_coroutine服务于TCP连接,在特定实例挂起时,如何调用my_coroutine的其他实例,等待async_foo完成?

解决方法

简而言之:

>当调用spawn()时,Boost.Asio执行一些设置工作,然后将使用stranddispatch()内部处理程序,该处理程序使用用户提供的函数作为入口点创建协同程序.在某些条件下,可以在对spawn()的调用调用内部处理程序,有时将其发布到io_service以进行延迟调用.
>协程暂停,直到操作完成并调用完成处理程序,io_service被销毁,或者Boost.Asio检测到协程已被挂起而无法恢复它,此时Boost.Asio将破坏协同程序.

如上所述,当调用spawn()时,然后使用strand来调度()内部处理程序,该处理程序使用用户提供的函数作为入口点创建协同程序.当yield_context对象作为处理程序传递给异步操作时,Boost.Asio将在使用完成处理程序启动异步操作后立即生成,该处理程序将复制结果并恢复协程.前面提到的链是由coroutine所有,用于保证在恢复之前产生的产量.让我们考虑一个简单的例子demonstrating spawn():

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

boost::asio::io_service io_service;

void other_work()
{
  std::cout << "Other work" << std::endl;
}

void my_work(boost::asio::yield_context yield_context)
{
  // Add more work to the io_service.
  io_service.post(&other_work);

  // Wait on a timer within the coroutine.
  boost::asio::deadline_timer timer(io_service);
  timer.expires_from_Now(boost::posix_time::seconds(1));
  std::cout << "Start wait" << std::endl;
  timer.async_wait(yield_context);
  std::cout << "Woke up" << std::endl;    
}

int main ()
{
  boost::asio::spawn(io_service,&my_work);
  io_service.run();
}

以上示例输出

Start wait
Other work
Woke up

这是尝试说明示例的执行.路径|表示活动堆栈,:表示挂起的堆栈,箭头用于表示控制转移:

boost::asio::io_service io_service;
boost::asio::spawn(io_service,&my_work);
`-- dispatch a coroutine creator
    into the io_service.
io_service.run();
|-- invoke the coroutine creator
|   handler.
|   |-- create and jump into
|   |   into coroutine         ----> my_work()
:   :                                |-- post &other_work onto
:   :                                |   the io_service
:   :                                |-- create timer
:   :                                |-- set timer expiration
:   :                                |-- cout << "Start wait" << endl;
:   :                                |-- timer.async_wait(yield)
:   :                                |   |-- create error_code on stack
:   :                                |   |-- initiate async_wait operation,:   :                                |   |   passing in completion handler that
:   :                                |   |   will resume the coroutine
|   `-- return                 <---- |   |-- yield
|-- io_service has work (the         :   :
|   &other_work and async_wait)      :   :
|-- invoke other_work()              :   :
|   `-- cout << "Other work"         :   :
|       << endl;                     :   :
|-- io_service still has work        :   :
|   (the async_wait operation)       :   :
|   ...async wait completes...       :   :
|-- invoke completion handler        :   :
|   |-- copies error_code            :   :
|   |   provided by service          :   :
|   |   into the one on the          :   :
|   |   coroutine stack              :   :
|   |-- resume                 ----> |   `-- return error code
:   :                                |-- cout << "Woke up." << endl;
:   :                                |-- exiting my_work block,timer is 
:   :                                |   destroyed.
|   `-- return                 <---- `-- coroutine done,yielding
`-- no outstanding work in 
    io_service,return.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...