我正在阅读文档boost::asio
并发现了这个例子:
void foo(boost::asio::yield_context yield)
{
size_t n = socket.async_read_some(buffer, yield);
// ...
}
我很困惑:
- 如果我正确理解了 asyncio,那么对 asyncio 的调用
async_read_some
就不会阻塞。 - 这意味着当数据真正准备好读取时,此调用将注册函数的其余部分以运行。
我看到两种boost::asio
实现方式:
- 当
socket.async_read_some
被调用时,此函数本身会调用事件循环中的一个函数,该函数尝试查找任何已准备好处理的事件并尝试调用这些回调。 - 一些
setjmp
/longjmp
magic 为该函数注册一个回调,并在稍后返回。
这两个选项似乎都不起作用:
- 调用堆栈看起来类似于:
...
boost_internal_magic
async_read_some
foo
...
main
因为我们还没有从 foo 返回。但是如果所有函数都使用 调用,yield_context
我不知道我们如何实际注册回调,因为没有代码点可以跳转到函数调用。
- 只有一个堆栈,但其全部目的
asyncio
是在同一线程上运行多个并发“代理”或“协同程序”或其他东西。每个代理都需要自己的堆栈,因此这似乎也行不通。
如何boost::asio::yield_context
将函数转换为可注册的回调?具有相同功能的最小无依赖 C++ 代码是什么样的?