对象 boost::asio::io_service 的 post() 方法是否使用 boost::coroutines 来执行处理程序中执行的短任务队列?这可以节省使用线程时同步所花费的资源,但无法将任务移动到另一个线程。或者说这没有任何意义?
最佳答案
据我所知,Boost.Asio 不使用协程。
从实现的角度来看,我会想象使用协程,例如Boost.Coroutine提供的协程。 ,在调用发布的处理程序时会引入开销。当事件循环知道可以调用哪些处理程序时,它可以简单地调用处理程序,而不必在蹦床函数中 boost 处理程序,以便可以在以下上下文中透明地调用它:一个协程。
Boost.Asio 不知道处理程序的实际或预期运行时间,因此无论处理程序如何,它都必须执行相同的内部同步。当 io_service 仅由单个线程处理时,可以通过提供 concurrency_hint 来减轻同步开销。施工期间。其他区域,例如 react 堆,可能仍需要执行同步。
最后,Boost.Asio 没有强加执行上下文,而是提供了一个强大的工具包,使用户能够为自己选择最佳选项。当前的 Boost.Asio Boost 1.54 候选版本通过其一流的支持 boost 了这种体验:
Stackful Coroutines基于Boost.Coroutine。下面是一个示例,其中
do_echo
作为协程在my_strand
上下文中执行。每个异步操作在启动异步操作后都会将控制权交还给调用线程,并且当调用完成处理程序时,控制权将立即返回到前一个让出点之后。boost::asio::spawn(my_strand, do_echo); // ... void do_echo(boost::asio::yield_context yield) { try { char data[128]; for (;;) { std::size_t length = my_socket.async_read_some( boost::asio::buffer(data), yield); boost::asio::async_write(my_socket, boost::asio::buffer(data, length), yield); } } catch (std::exception& e) { // ... } }
Boost.Asio提供了完整的echo_service example使用 Stackful Coroutines。
Stackless Coroutines已从HTTP Server 4 example boost 为记录的公共(public)API 。这些是作为 Duff 设备的变体实现的,但通过使用伪关键字
reenter
、yield
和fork
完全隐藏了细节。以下内容大致相当于上面的 Stackful Coroutine 示例:struct session : boost::asio::coroutine { tcp::socket my_socket_; char data_[128]; // ... void operator()(boost::system::error_code ec = boost::system::error_code(), std::size_t length = 0) { if (!ec) reenter (this) { for (;;) { yield my_socket_.async_read_some( boost::asio::buffer(data_), *this); yield boost::asio::async_write(my_socket_, boost::asio::buffer(data_, length), *this); } } } };
请参阅
boost::asio::coroutine
文档以获取更多详细信息。
虽然我不知道使用协程构建异步调用链是否有性能优势,但我觉得它们最大的贡献是可维护性和可读性。我发现能够以同步方式读写异步程序有助于降低反向控制流带来的复杂性,因为现在可以消除操作启动和完成之间的空间分离。
关于boost - 对象 boost::asio::io_service 的方法 post() 是否使用 boost::coroutines 来执行短任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17261191/