asio::strand<asio::io_context::executor_type> 对比 io_context::strand

asio::strand<asio::io_context::executor_type> vs io_context::strand

自从最新版本的 boost 以来,asio 推出了新的执行器并提供了 asio::strand<Executor>。所以现在完全可以使用 asio::strand<asio::io_context::executor_type> 而不是 io_context::strand。但它们不能互换使用。

io_context::strand 是“遗产”。我假设它的存在是为了与仍然使用 boost::asio::io_service(也已弃用)的代码实现接口兼容性。

As the comments reflect I've since found out that io_context::strand is not actually deprecated, although I see no reason why this is the case, and close reading of the implementation leaves me with the conclusion that

  • asio::strand<Executor> is strictly better

  • mixing both strand services is not the best idea. In fact both services are documented with the same tag line:

     // Default service implementation for a strand.
    

    I can't help feeling there should be only one default :)

现代链不引用执行上下文,而是包装执行程序。

虽然在技术上有所不同,但在概念上是相同的。

发布任务用法相同:

post(s, task); // where s is either legacy or modern 
defer(s, task);
dispatch(s, task);

In fact you may have tasks with an associated executor, see:

您不能再使用遗留链来构造 IO 服务对象(如 tcp::socket 或 steady_timer)。那是因为不能将遗留链类型擦除为 any_io_executor:

using tcp = boost::asio::ip::tcp;
boost::asio::io_context ioc;

auto modern = make_strand(ioc.get_executor());
tcp::socket sock(modern);

boost::asio::io_context::strand legacy(ioc);
tcp::socket sock(legacy); // COMPILE ERROR

如果你真的想要,你可以通过不使用来强制它 any_io_executor:

boost::asio::basic_stream_socket<tcp, decltype(legacy)> sock(legacy);
sock.connect({{}, 8989});