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

手写muduo网络库(零):多线程中使用 weakptr 跨线程监听生命状态

在着手手写 muduo 网络库时,多线程编程中的对象生命周期管理是绕不开的关键技术点。std::weak_ptr作为 C++ 标准库的重要工具,能帮助我们在多线程环境下优雅、安全地监听对象生命状态,为网络库的稳定性和可靠性奠定基础。接下来,我们深入探讨这一前置知识,并结合实际场景,为手写 muduo 网络库做好技术储备。

一、核心概念解析​

1.1 std::shared_ptr与std::weak_ptr的协作机制​

在 muduo 网络库中,会存在大量需要多线程共享访问的对象,如连接管理对象、事件循环对象等。std::shared_ptr通过引用计数管理对象生命周期,在共享这些对象时,引用计数随着新std::shared_ptr的创建而增加,随着std::shared_ptr的销毁而减少,引用计数为 0 时对象自动销毁,为对象共享提供了基础保障。​

std::weak_ptr则是对std::shared_ptr所管理对象的弱引用,不影响对象生命周期,却能检查对象是否存在。在手写 muduo 时,std::weak_ptr可用于在多个线程交互场景下,安全判断对象是否存活。比如,当一个线程负责处理网络连接,另一个线程可能对连接对象进行销毁操作,std::weak_ptr就能避免处理线程访问已销毁的连接对象。​

1.2 线程安全特性​

std::shared_ptr和std::weak_ptr的引用计数操作具备线程安全性,这对于多线程的 muduo 网络库来说,保证了对象生命周期管理在多线程环境下的正确性。但要注意,对象本身的读写操作并非线程安全,在手写 muduo 时,我们需要借助互斥锁等同步机制,来确保对象访问的线程安全,防止出现数据竞争问题。

二、实现步骤与代码示例

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>class Monitorable {
public:Monitorable() { std::cout << "Monitorable created" << std::endl; }~Monitorable() { std::cout << "Monitorable destroyed" << std::endl; }void doWork() {std::lock_guard<std::mutex> lock(mtx_);std::cout << "Working..." << std::endl;}private:std::mutex mtx_;
};void workerThread(std::weak_ptr<Monitorable> weakObj) {// 模拟耗时操作std::this_thread::sleep_for(std::chrono::seconds(1));// 尝试锁定弱引用,检查对象是否存活if (auto sharedObj = weakObj.lock()) {// 对象存活,可以安全使用sharedObj->doWork();} else {// 对象已销毁std::cout << "Object expired, skipping work" << std::endl;}
}int main() {{auto sharedObj = std::make_shared<Monitorable>();std::thread t(workerThread, sharedObj);t.detach(); // 分离线程,让它在后台运行// 主线程作用域结束前,sharedObj可能被销毁} // sharedObj在此处被销毁// 主线程继续执行其他任务std::this_thread::sleep_for(std::chrono::seconds(2));return 0;
}
  • 线程函数参数传递:在workerThread 函数中,使用std::weak_ptr 作为参数接收对象引用。这样做的好处是,std::weak_ptr 不会增加对象的引用计数,从而不会影响对象的正常生命周期管理。即使主线程中std::shared_ptr 被销毁,workerThread 中的std::weak_ptr 仍能用于检查对象状态。​
  • 对象状态检查方式:在workerThread 函数中,通过调用weakObj.lock() 尝试获取对象的 std::shared_ptr 。如果对象仍然存在,lock() 会返回一个有效的 std::shared_ptr ,此时可以安全地访问对象的成员函数;如果对象已被销毁,lock() 则返回 nullptr ,从而避免了悬空指针的风险。​
  • 线程安全保障措施:在Monitorable 类的doWork 函数中,使用std::lock_guard<std::mutex> 来保证多线程访问对象资源时的线程安全。通过互斥锁,确保在同一时刻只有一个线程能够执行doWork 函数,防止数据竞争和不一致的情况发生。

 三、注意要点

  • 对象销毁延迟:虽然std::weak_ptr 的状态检查是原子操作,但对象的实际销毁可能会有延迟,这取决于 std::shared_ptr 的释放顺序。因此,在检查对象状态和实际使用对象之间,仍需考虑对象可能被销毁的情况,避免出现逻辑错误。​
  • 线程安全补充:尽管std::shared_ptr 和 std::weak_ptr 的引用计数操作线程安全,但在使用 lock() 返回的 std::shared_ptr 访问对象时,仍要结合其他同步机制(如互斥锁),确保对象的读写操作在多线程环境下的安全性。​

掌握std::weak_ptr在多线程中监听对象生命状态的方法,是手写 muduo 网络库的重要前置知识。它能帮助我们有效管理对象生命周期,避免悬空指针等问题,为后续构建稳定、可靠的 muduo 网络库打下坚实基础。

http://www.lqws.cn/news/183241.html

相关文章:

  • 智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网
  • 微算法科技(NASDAQ:MLGO)基于信任的集成共识和灰狼优化(GWO)算法,搭建高信任水平的区块链网络
  • K8S认证|CKS题库+答案| 3. 默认网络策略
  • 郑州工程技术学院赴埃文科技开展访企拓岗促就业活动
  • 第三方测试机构进行科技成果鉴定测试有什么价值
  • JeecgBoot低代码管理平台
  • 沙市区举办资本市场赋能培训会 点赋科技分享智能消费新实践
  • 超大规模芯片验证:基于AMD VP1902的S8-100原型验证系统实测性能翻倍
  • 因泰立科技H1X激光雷达:因泰立科技为智慧工业注入新动力
  • Unreal从入门到精通之 UE4 vs UE5 VR性能优化实战
  • 开源 vGPU 方案:HAMi,实现细粒度 GPU 切分
  • NLP学习路线图(二十八):BERT及其变体
  • 「基于连续小波变换(CWT)和卷积神经网络(CNN)的心律失常分类算法——ECG信号处理-第十五课」2025年6月6日
  • 2025年,百度智能云打响AI落地升维战
  • 【计算机组成原理 第5版】白、戴编著 第六章 总线系统 课后题总结
  • C++ if语句完全指南:从基础到工程实践
  • Python60日基础学习打卡Day45
  • 在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
  • SCAU数值计算OJ
  • Elasticsearch集群手动分片分配指南:原理与实践
  • 国芯思辰| AD7894的优质替代方案:SC1424模数转换器在分布式控制系统中的应用优势
  • c++中的输入输出流(标准IO,文件IO,字符串IO)
  • 2025年6月6日 奇门遁甲与股市
  • 加密货币钱包开发指南:多链资产管理与非托管安全范式
  • 在SpringBoot中使用AWS SDK实现邮箱验证码服务
  • AWS API Gateway配置日志
  • 强化学习基础概念图文版笔记
  • SpringCloud学习笔记-3
  • 《UE5_C++多人TPS完整教程》学习笔记37 ——《P38 变量复制(Variable Replication)》
  • Python打卡DAY46