我可以通过以下方式使用stackful coroutine和boost::asio::steady_timer::async_wait
吗?
重点是(我的理解,不确定)在等待期间,局部变量timer
不在堆栈中,因此无法访问。那么回调能否正常进行? (仅供参考,它使用clang ++ 5.0在我的Mac上运行正常。)
boost::asio::io_service io;
void Work(boost::asio::yield_context yield) {
boost::asio::steady_timer timer(io);
timer.expires_from_now(std::chrono::seconds(5));
timer.async_wait(yield);
cout << "Woke up." << endl;
}
int main() {
boost::asio::spawn(io, Work);
io.run();
return 0;
}
我认为值得对这个问题进行比较:boost asio deadline_timer
答案 0 :(得分:8)
是的,将boost::asio::yield_context
传递给在同一协程中具有自动存储持续时间的对象是安全的。
Boost.Coroutine使用Boost.Context执行上下文切换。 Boost.Context提供了一种暂停当前执行路径,保留堆栈(包括Work()
的{{1}}等局部变量)和传输执行控制的方法,允许相同的线程以不同的方式运行堆。因此,如果timer
对象具有自动存储持续时间,则其寿命将在以下任一时间结束:
boost::asio::steady_timer
退出Work()
指定的块,到达函数结尾或展开堆栈的异常。return
已被销毁。内部处理程序维护协程的共享所有权,当io_service
被销毁时,所有关联的处理程序也会被销毁。这种破坏将导致Boost.Coroutine强制每个协程的堆栈展开。当调用boost::asio::spawn()
时,Boost.Asio执行一些设置工作,然后dispatch()将使用用户提供的函数作为入口点创建协程的内部处理程序。当io_service
对象作为处理程序传递给异步操作时,Boost.Asio将在使用完成处理程序启动异步操作后立即产生,该处理程序将复制结果并且 resume 他们的协程。协程所拥有的strand
用于保证在 resume 之前发生 yield 。这是尝试说明示例代码的执行:
yield_context
答案 1 :(得分:2)