首页 > 解决方案 > 如何正确存储和调用`boost::asio`处理程序?

问题描述

目前,我正在使用boost::asio框架实现一个有点复杂的网络协议。该协议支持请求多路复用,因此我实现了一个有状态的组合操作来提供高级访问。说,类似于以下内容:

connection::async_request(Request req, Handler&& h);

此请求允许同时运行,因此我必须在内部收集容器中的所有待处理完成处理程序,以便能够为每个请求调用适当的处理程序。不幸的是,boost::asio Handler不仅仅是一个,所以这里不能使用Callable一个容器。std::function<>AFAIU,每个Handler都由三部分组成:

另外boost::asio::executor_work_guard<Executor>,对象必须与对象一起存储,Handler以防止关联Executor对象因缺少工作而终止。我没有在 Boost.Asio 库中找到任何准备好的东西。我对吗?

我发现boost::beast::saved_handlerBoost.Beast 库中有一个,我想它是为同样的问题而设计的。但是,我看到它saved_handler::invoke()被设计为普通的函数调用。据我了解,当处理程序关联的执行程序与组合操作的内部处理程序的执行程序不同时,这可能会导致问题。所以这部分对我来说仍然不清楚。

组合操作 Asio 示例 ( cpp14/operations) 继承了与内部异步操作相关的分配器和执行器的处理程序。相反,我在内部connection::async_request使用async_write/async_readstrand对象,需要提供正确的实现。同时,Handler传递给函数的可能使用另一个strand,在组合操作过程中不能丢失。我是否理解正确,运行boost::asio::dispatch()是调用存储处理程序的更正确方法?应该推荐什么方式来提供这种功能?

更新: @sehe 向我指出了 Reddit 线程:https ://www.reddit.com/r/cpp/comments/6aygos/boostasio_asynchronous_composed_operation_tutorial/

我将用引用的线程的术语重新表述我的问题,如下所示。Asio 对组合操作如何在内部工作做出以下假设:

当异步操作由其他异步操作组成时,应使用与最终处理程序相同的方法调用所有中间处理程序。

这可能就是为什么调用最终处理程序的原因,就像handler(...)在 Internet 上找到的所有示例一样。(可能包括beast::saved_handler实施)。

不幸的是,这不是我的情况。connection::async_request开始新的组合异步操作或将更多工作附加到已经进行的操作。在后一种情况下,用户提供的新的最终处理程序不会影响调用中间处理程序的方式(Executor和)。Allocator

标签: c++boostboost-asio

解决方案


推荐阅读