无Boost依赖的Asio多线程安全、strand替换及同步方法咨询
独立版Asio适配方案
1. strand定义替换方法
你原代码中的asio::strand<asio::io_context::executor_type> strand_;有两种兼容独立版Asio的替换方案:
- 低开销无类型擦除写法:不需要修改原有定义,只要确保你引入了
<asio/strand.hpp>头文件即可正常编译,该模板定义在独立版Asio中完全保留。 - 更简洁的类型擦除写法:直接将成员变量声明为
asio::any_io_executor strand_;,初始化逻辑保持strand_(asio::make_strand(io))不变即可,无需调整其他调用代码。
同时需要注意,独立版Asio不需要依赖Boost库的绑定工具,直接把代码中的boost::bind替换为std::bind即可,也可以使用lambda表达式简化写法,修改后的完整示例代码如下:
#include <asio.hpp> #include <functional> class printer { public: printer(asio::io_context& io) : strand_(asio::make_strand(io)), timer1_(io, asio::chrono::seconds(1)), timer2_(io, asio::chrono::seconds(1)), count_(0) { timer1_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print1, this, std::placeholders::_1))); timer2_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print2, this, std::placeholders::_1))); } private: asio::any_io_executor strand_; asio::steady_timer timer1_; asio::steady_timer timer2_; int count_; void print1(const asio::error_code& ec) { if (!ec && count_ < 10) { timer1_.expires_after(asio::chrono::seconds(1)); timer1_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print1, this, std::placeholders::_1))); ++count_; } } void print2(const asio::error_code& ec) { if (!ec && count_ < 10) { timer2_.expires_after(asio::chrono::seconds(1)); timer2_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print2, this, std::placeholders::_1))); ++count_; } } };
2. 多线程Asio handler同步方案
多线程场景下Asio的handler同步优先使用strand机制,不需要手动加锁:
- 只要所有需要访问共享资源的handler都通过
asio::bind_executor绑定到同一个strand实例上,Asio会自动保证这些handler不会并发执行,不会出现竞态问题,性能也优于手动加互斥锁的方案。 - 只有当handler中需要访问的共享资源同时会被Asio回调之外的线程操作时,才需要额外配合
std::mutex等同步原语使用,普通的Asio回调内的共享资源访问用strand即可完全覆盖。
3. 独立版Asio学习资源推荐
- Asio官方文档:官方文档本身就明确区分了Boost.Asio和独立Asio的用法,所有标注了支持标准库的接口都可以直接在独立Asio中使用。
- 国内C++技术社区实战内容:很多后端开发从业者会分享独立Asio的高并发网络编程、跨平台编译、协程适配、性能优化等场景的落地经验。
- C网络TS相关文档:Asio是C标准网络库的核心参考实现,相关标准提案文档可以帮助你理解Asio的接口设计逻辑,适合进阶学习。
内容的提问来源于stack exchange,提问作者Olich
相关产品推荐
相关产品推荐

