asio::strand<asio::io_context::executor_type> vs io_context::strand
Posted
技术标签:
【中文标题】asio::strand<asio::io_context::executor_type> vs io_context::strand【英文标题】: 【发布时间】:2021-03-23 14:24:20 【问题描述】:自从最新版本的 boost,asio 提供了新的执行器并提供了asio::strand<Executor>
。所以现在完全可以使用asio::strand<asio::io_context::executor_type>
而不是io_context::strand
。但它们不能互换使用。
【问题讨论】:
【参考方案1】:io_context::strand
是“旧版”。我认为它的存在是为了与仍然使用boost::asio::io_service
(也已弃用)的代码兼容。
正如 cmets 反映的那样,我发现
io_context::strand
实际上并没有被弃用,尽管我看不出为什么会出现这种情况,仔细阅读实施后我得出的结论是
asio::strand<Executor>
更好混合这两种服务并不是最好的主意。事实上,这两种服务都使用相同的标签行记录:
// Default service implementation for a strand.
我不禁觉得应该只有一个默认值:)
现代链不引用执行上下文,而是包装一个执行器。
虽然在技术上有所不同,但在概念上是相同的。
发布任务的用法相同:
post(s, task); // where s is either legacy or modern
defer(s, task);
dispatch(s, task);
事实上,您可能有与 关联的执行者 相关的任务,请参阅:
When must you pass io_context to boost::asio::spawn? (C++) Which io_context does std::boost::asio::post / dispatch use?
您不能再使用遗留链来构造 IO 服务对象(如 tcp::socket 或 stable_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);
【讨论】:
修复了一些准确性问题并添加了相关示例。 嗨@sehe,感谢您的明确回答。只需再次交叉检查最新的 ASIO 文档(boost 1.75 和独立 1.18.1),我没有看到 io_context::strand 已弃用。无论如何,很高兴知道我最好选择 strandstrand
并没有像内部类型 work
那样被弃用(make_strand
和 strand<executor_type>
似乎类似于 make_work_guard
和 executor_work_guard<executor_type>
所以我在脑海中将它们联系起来)。令人惊讶的是,遗留链(我会一直这么称呼它)有它自己的 separate IO 服务实现支持它(strand_service
),它 99% 复制了新的 strand_executor_service
。后者严格来说更加通用和灵活(例如 w.r.t 组合/修改的执行器)
我看到的唯一功能区别是,不能再强制使用不同数量的链“桶”(~唯一互斥体实例的数量)(使用 BOOST_ASIO_STRAND_IMPLEMENTATIONS
作为explained in this easily underrated answer @TannerSansbury . 并且请注意,当同时使用这两种 strand 服务时,您实际上将 strand 实现的数量增加了一倍。我发现这两者都存在而没有被弃用的情况令人惊讶。
(修正了我在答案文本中的错误声明)以上是关于asio::strand<asio::io_context::executor_type> vs io_context::strand的主要内容,如果未能解决你的问题,请参考以下文章
boost::asio: “strand”类型的同步原语有啥名字吗?
如果调用 asio::strand 的析构函数时,该链上仍有一些就绪/未就绪的处理程序怎么办?
boost::asio::strand 在 Ubuntu 11.04 (boost_all_dev 1.42) 上是不是损坏