C++ asio::斯特兰德<;asio::io_上下文::执行器_类型>;vs io_上下文::串

C++ asio::斯特兰德<;asio::io_上下文::执行器_类型>;vs io_上下文::串,c++,boost-asio,C++,Boost Asio,自boost的最新版本以来,asio推出了新的执行器,并提供了asio::strand。因此,现在完全可以使用asio::strand而不是io\u context::strand。但它们不能互换使用 有人能举例说明用法上的区别吗 他们与其他人相比的优势/不便 io_上下文::strand是“遗留”。我假设它的存在是为了与仍然使用boost::asio::io_服务的代码兼容(也不推荐使用) 正如评论所反映的那样,我后来发现io_context::strand实际上并没有遭到反对,尽管我看不出

自boost的最新版本以来,asio推出了新的执行器,并提供了
asio::strand
。因此,现在完全可以使用
asio::strand
而不是
io\u context::strand
。但它们不能互换使用

  • 有人能举例说明用法上的区别吗
  • 他们与其他人相比的优势/不便

io_上下文::strand是“遗留”。我假设它的存在是为了与仍然使用
boost::asio::io_服务的代码兼容(也不推荐使用)

正如评论所反映的那样,我后来发现
io_context::strand
实际上并没有遭到反对,尽管我看不出为什么会这样,仔细阅读实现后,我得出了这样的结论:

  • asio::strand
    绝对更好

  • 混合这两种串服务不是最好的主意。事实上,这两项服务都使用相同的标记行记录:

     // Default service implementation for a strand.
    
    我不禁觉得应该只有一个默认值:)

现代链不引用执行上下文,而是包装一个执行者

虽然技术上不同,但概念上是相同的

发布任务的用法相同:

post(s, task); // where s is either legacy or modern 
defer(s, task);
dispatch(s, task);
事实上,您可能与关联的执行者有任务,请参阅:

您不能再使用遗留链来构造IO服务对象(如tcp::socket或Stadium\u timer)。这是因为不能将遗留链类型擦除到任何io执行器中:

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
boost::asio::basic_stream_socket<tcp, decltype(legacy)> sock(legacy);
sock.connect({{}, 8989});
如果确实需要,可以通过不使用任何io执行器来强制执行:

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
boost::asio::basic_stream_socket<tcp, decltype(legacy)> sock(legacy);
sock.connect({{}, 8989});
boost::asio::basic\u stream\u socket sock(遗留);
sock.connect({{},8989});

修复了一些准确性问题,并添加了相关示例。您好@sehe,谢谢您的明确回答。只要再次交叉检查最新的ASIO文档(boost 1.75和standalone 1.18.1),我不认为io_context::strand已被弃用。不管怎样,很高兴知道我最好选择strand版本。天啊。我一直在想我知道Asio。然后我证明自己错了。我很惊讶,内部类型
strand
没有像内部类型
work
那样被弃用(
make_-strand
strand
似乎类似于
make_-work\u-guard
executor\u-work\u-guard
,所以我把它们联系在一起)。令人惊讶的是,传统的strand(我一直这么说)有自己独立的IO服务实现支持它(
strand\u service
),它99%复制了较新的
strand\u executor\u service
。后者严格来说更通用、更灵活(例如w.r.t组合/修改的执行器)。我看到的唯一功能区别是,不能再强制使用不同数量的串“bucket”(~唯一互斥实例的数量)(使用@TannerSansbury提供的
BOOST\u ASIO\u STRAND\u实现
。请注意,在使用这两种STRAND服务时,您实际上将STRAND实现的数量增加了一倍。我发现这两种实现都存在而没有一种被弃用,这让我感到惊讶。(修复了我在回答文本中的错误声明)