当前位置: 首页 > news >正文

在串口通信中使用共享指针(`std::shared_ptr`)

在串口通信中使用共享指针(std::shared_ptr)可以有效管理资源生命周期,避免内存泄漏和悬挂指针问题。以下是关键步骤和注意事项:


1. 管理串口对象生命周期

  • 创建共享指针:使用 std::make_shared 初始化串口对象,确保资源自动管理。

    #include <boost/asio.hpp>
    #include <memory>auto port = std::make_shared<boost::asio::serial_port>(io_context);
    port->open("/dev/ttyUSB0");
    
  • 绑定到异步操作:在异步读写中捕获 shared_ptr,确保回调执行期间对象存活。

    port->async_read_some(boost::asio::buffer(data),[port, data](const boost::system::error_code& ec, size_t bytes) {if (!ec) {// 处理数据,port 对象保持有效}});
    

2. 管理缓冲区

  • 动态缓冲区:使用 shared_ptr 包裹数据缓冲区,避免异步操作未完成时数据被释放。
    auto buffer = std::make_shared<std::vector<char>>(1024);
    port->async_write_some(boost::asio::buffer(*buffer),[buffer, port](const boost::system::error_code& ec, size_t bytes) {// 写入完成前,buffer 保持有效});
    

3. 避免循环引用

  • 使用 weak_ptr:若回调中需要访问父对象,使用 std::weak_ptr 打破循环引用。
    class SerialHandler {
    public:void start_read() {auto self = weak_from_this(); // C++17 的 weak_from_thisport_->async_read_some(/* ... */,[self](/* ... */) {if (auto ptr = self.lock()) {ptr->handle_read(ec, bytes);}});}
    private:std::shared_ptr<boost::asio::serial_port> port_;
    };
    

4. 自定义删除器

  • 释放资源:某些库需手动关闭串口,通过自定义删除器确保正确释放。
    auto deleter = [](boost::asio::serial_port* port) {if (port->is_open()) port->close();delete port;
    };
    std::shared_ptr<boost::asio::serial_port> port(new boost::asio::serial_port(io_context), deleter);
    

5. 线程安全与性能

  • 原子性操作shared_ptr 的引用计数是线程安全的,但对象内部仍需同步。
    std::mutex mtx;
    port->async_read_some(/* ... */,[port, &mtx](/* ... */) {std::lock_guard<std::mutex> lock(mtx);// 安全访问共享资源});
    
  • 性能权衡:高频通信中,shared_ptr 的原子操作可能影响性能,可考虑对象池或静态分配。

6. 示例:完整异步读写

#include <boost/asio.hpp>
#include <memory>class SerialPort {
public:SerialPort(boost::asio::io_context& io, const std::string& device): port_(std::make_shared<boost::asio::serial_port>(io, device)) {}void start_async_read() {auto buffer = std::make_shared<std::vector<char>>(128);port_->async_read_some(boost::asio::buffer(*buffer),[this, buffer](const boost::system::error_code& ec, size_t bytes) {if (!ec) {process_data(*buffer, bytes);start_async_read(); // 持续读取}});}private:std::shared_ptr<boost::asio::serial_port> port_;void process_data(const std::vector<char>& data, size_t size) { /* ... */ }
};

注意事项

  • 资源释放:确保所有异步操作完成后,shared_ptr 的引用计数归零,避免内存泄漏。
  • 超时处理:长时间未响应的操作需设置超时,防止对象因回调未触发而无法释放。
  • 异常处理:在异步操作中捕获异常,确保 shared_ptr 能正常析构。

通过合理使用 shared_ptr,可以简化串口通信中的资源管理,提升代码健壮性。

相关文章:

  • 用 R 语言打造交互式叙事地图:讲述黄河源区生态变化的故事
  • MCP认证难题破解:常见技术难题实战分析与解决方案
  • 额外篇 非递归之美:归并排序与快速排序的创新实现
  • 基于Redis的3种分布式ID生成策略
  • JAVA文件I/O
  • 大数据平台简介
  • 《Operating System Concepts》阅读笔记:p738-p747
  • Java从入门到“放弃”(精通)之旅——数组的定义与使用⑥
  • 批量创建OpenStack实例
  • 【java实现+4种变体完整例子】排序算法中【堆排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
  • doris/clickhouse常用sql
  • C++镌刻数据密码的树之铭文:二叉搜索树
  • 与终端同居日记:Linux指令の进阶撩拨手册
  • 区块链木材业务服务平台:商贸物流新变革
  • 18、TimeDiff论文笔记
  • 【综述】一文读懂卷积神经网络(CNN)
  • 【2025】Datawhale AI春训营-RNA结构预测(AI+创新药)-Task2笔记
  • [dp20_完全背包] 介绍 | 零钱兑换
  • 包含物体obj与相机camera的 代数几何代码解释
  • 220V转5V转12V电机驱动供电WT5105
  • “站在亚洲实现整体振兴的新起点上”——习近平主席对越南、马来西亚、柬埔寨进行国事访问纪实
  • 澳门世界杯“中日对决”,蒯曼击败伊藤美诚晋级女单决赛
  • 文理医工“四轮驱动”,复旦六大新工科创新学院核心团队均亮相
  • 习近平主席东南亚三国行|元首外交硕果累累 • 一图读懂
  • 杭州:调整个人购买家庭住房享受契税优惠住房套数查询规则
  • 强对流+暴雨+大雾,中央气象台三预警齐发