Cpp*_*oob 7 c++ boost boost-asio boost-coroutine
我无法形成关于控制流如何与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
完成?
Tan*_*ury 24
简而言之:
spawn()
被调用时,执行Boost.Asio的一些设置工作,然后将使用一个strand
给dispatch()
创建使用所提供的功能的入口点的用户协同程序的内部处理程序.在某些条件下,内部处理程序可以在调用期间调用spawn()
,有时则将其发布到io_service
for forferred调用.io_service
销毁,或者Boost.Asio检测到协程已被暂停而无法恢复它,此时Boost.Asio将破坏协程.如上所述,当spawn()
被调用时,执行Boost.Asio的一些设置工作,然后将使用一个strand
给dispatch()
创建使用所提供的功能的入口点的用户协同程序的内部处理程序.当yield_context
对象作为一个处理程序,异步操作过去了,Boost.Asio的会产生启动与完成处理,将结果复制和异步操作后立即恢复的协同程序.前面提到的链是由coroutine拥有,用于保证在恢复之前发生的产量.让我们考虑一个简单的例子来证明: 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();
}
Run Code Online (Sandbox Code Playgroud)
以上示例输出:
Start wait
Other work
Woke up
Run Code Online (Sandbox Code Playgroud)
这是尝试说明示例的执行.路径|
指示活动堆栈,:
指示挂起的堆栈,箭头用于指示控制转移:
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.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4648 次 |
最近记录: |