尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
muduo网络库(九):Thread 线程类封装
muduo网络库九Thread 线程类封装muduo网络库九Thread 线程类封装概述析构函数的自动清理机制为什么 thread_ 要用智能指针Two-Phase Construction 两段式构造两段式构造的优势与一步式构造的对比start 中的 run 方法核心成员变量设计精髓总结muduo网络库九Thread 线程类封装概述Thread类是对std::thread的封装提供了更易用、更安全的线程管理接口。原生std::thread虽然功能强大但直接使用存在一些陷阱——比如忘记 join 或 detach 就会导致程序崩溃、无法延迟启动线程等。muduo 的Thread类通过智能指针延迟初始化和两段式构造解决了这些问题。析构函数的自动清理机制Thread::~Thread(){if(started_!joined_){thread_-detach();// thread 类提供的设置分离线程的方法}}detach()将线程与当前线程对象分离使其成为守护线程。分离后的线程会在执行完毕后自动释放资源生命周期不受 Thread 对象控制。为什么必须这样设计因为 C 标准规定如果一个std::thread对象在析构时线程仍在运行且既未被join也未被detach程序会直接调用std::terminate()崩溃退出。该析构函数实现了线程资源的自动清理条件动作原因started_ false不处理线程从未启动无需清理joined_ true不处理已被 join线程已结束started_ !joined_自动 detach防止析构崩溃遵循 RAII这遵循了RAII 原则Resource Acquisition Is Initialization资源的获取就是对象初始化的时机资源的释放就是对象析构的时机。Thread 对象的生命周期即线程资源的生命周期安全且自动化。为什么 thread_ 要用智能指针如果直接定义std::thread thread_作为成员变量会导致严重问题// ❌ 错误做法直接声明classThread{std::thread thread_;// 构造函数调用时线程会立即开始执行}; std::thread 的特性是**一旦构造完成线程立即开始执行**。如果直接声明为成员变量在 Thread 类的构造函数执行时线程就已经启动了——但此时可能还没有完成必要的配置工作。 使用 std::shared_ptrstd::thread 智能指针的好处1.**延迟初始化**构造函数中只是声明空指针不创建线程在 start() 时才真正创建 std::thread 对象实现先创建对象、后启动线程的灵活模式2.**批量创建统一启动**可以先创建多个 Thread 对象配置好各自的任务再统一调用 start() 启动3.**资源管理自动化**智能指针自动管理 std::thread 对象的内存无需手动 delete避免内存泄漏 cpp// ✓ 正确做法智能指针延迟初始化classThread{std::shared_ptrstd::threadthread_;// 初始为 nullptr// 在 start() 中才创建thread_ std::make_sharedstd::thread(...)};Two-Phase Construction 两段式构造muduo 的 Thread 类采用两段式构造模式将对象创建和线程启动分为两个独立阶段// 第一阶段创建对象不启动线程Thread(ThreadFunc func,conststd::stringname):started_(false),joined_(false),func_(std::move(func)),name_(name){}// 第二阶段显式启动线程voidstart(){assert(!started_);started_true;// 此时才真正创建 std::thread 对象thread_std::make_sharedstd::thread(std::bind(Thread::run,this));}两段式构造的优势优势说明灵活可控先创建 Thread 对象做配置需要时再start()启动批量创建可以先创建多个 Thread 对象统一启动错误处理如果配置阶段出错尚未创建线程无需清理线程资源线程 ID 管理启动后可以获取 tid在启动前就预留了记录线程信息的时机与一步式构造的对比// 一步式构造即启动std::threadt(myFunc);// 立即执行无法延迟// 两段式构造 启动分离Threadt(myFunc);// 此时线程未启动t.start();// 此时才启动两段式构造特别适合需要精确控制线程生命周期的场景比如线程池中预先创建 Thread 对象根据负载动态启动。start 中的 run 方法start()内部创建std::thread时绑定的是Thread::run而非直接传入用户函数thread_std::make_sharedstd::thread(std::bind(Thread::run,this));run()方法内部会先记录当前线程 ID配合CurrentThread::tid()然后执行用户传入的func_。这样设计使得线程启动后自动设置线程名和线程 ID线程退出时可以执行清理逻辑上层可以通过线程名进行调试和监控核心成员变量boolstarted_;// 是否已启动booljoined_;// 是否已被 joinstd::shared_ptrstd::threadthread_;// 智能指针管理的线程对象ThreadFunc func_;// 线程执行函数std::string name_;// 线程名称started_和joined_作为状态标志用于析构函数判断是否需要自动 detachfunc_使用std::move转移所有权避免不必要的拷贝name_方便调试时识别线程配合CurrentThread使用设计精髓总结设计点做法收益自动 detach析构函数检查状态防止未 join/detach 导致崩溃智能指针shared_ptrstd::thread延迟初始化资源自动管理两段式构造构造 start 分离灵活控制启动时机状态标志started_ / joined_析构时精确判断处理方式RAII对象生命周期 资源生命周期线程资源安全释放muduo 的 Thread 类虽然只是对std::thread的封装但每一处设计都体现了工程智慧自动 detach 防止崩溃、智能指针实现延迟初始化、两段式构造赋予灵活控制能力。这些设计让多线程编程更安全、更易用。
RELATED

相关推荐

三步轻松备份QQ空间历史说说:GetQzonehistory终极指南

三步轻松备份QQ空间历史说说:GetQzonehistory终极指南

三步轻松备份QQ空间历史说说:GetQzonehistory终极指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾担心QQ空间里那些承载青春记忆的说说会随着时间消失&#xff…

📅 2026/8/25 3:51:20
PVZ创意工坊最高难度通关策略:从阵容搭配到微操技巧

PVZ创意工坊最高难度通关策略:从阵容搭配到微操技巧

最近在重温经典塔防游戏《植物大战僵尸》时,发现很多玩家对创意工坊和高难度挑战情有独钟。特别是像"诺亚实况"这类极限玩法视频,总能吸引大量关注。本文将系统拆解PVZ创意工坊的最高难度通关策略,从基础阵容搭配到进阶微操技巧&am…

📅 2026/8/25 3:51:20
应对气象大数据处理的挑战:MeteoInfo平台架构设计与工程实践深度解析

应对气象大数据处理的挑战:MeteoInfo平台架构设计与工程实践深度解析

应对气象大数据处理的挑战:MeteoInfo平台架构设计与工程实践深度解析 【免费下载链接】MeteoInfo MeteoInfo: GIS, scientific computation and visualization environment. 项目地址: https://gitcode.com/gh_mirrors/me/MeteoInfo 气象数据处理面临着数据格…

📅 2026/8/25 3:51:20
MORE NEWS

更多资讯

📰

腾讯拍拍面试必问:3招讲透底层逻辑

腾讯拍拍面试必问:3招讲透底层逻辑 官方文档动辄几百页,翻到第二页就晕头转向?别慌,这很正常。 面试必问的腾讯拍拍架构题,往往就藏在你没注意的边角料里。 今天咱们不背八股文,直接拆骨架,用3分钟把核心逻辑刻进脑子。…

📰

Wave Summit 2020源码剖析:从入门到精通的避坑指南

Wave Summit 2020源码剖析:从入门到精通的避坑指南 是不是也这样?教程看了几百个,代码敲了上千行,真让你从零搭个项目,脑子一片空白。这种“手眼分离”的尴尬,在Wave Summit…

📰

3个坑让单反价格选型难?手写实现配置避坑指南

3个坑让单反价格选型难?手写实现配置避坑指南 配置环境就卡半天,是不是你的常态?明明照着教程一步步来,结果依赖冲突、版本不对,折腾一下午还没跑通。这种痛苦,老手都懂。今天不聊虚的,直接上干货,通过 手写实现…

📰

Ubuntu离线安装RTL8852BE驱动:从依赖到DKMS完整指南

前几天给一台闲置笔记本装 Ubuntu 20.04,系统装完了,网卡却变成了一块废铁。lspci里清清楚楚写着Realtek Semiconductor Co., Ltd. Device b852,也就是很常见的 RTL8852BE Wi-Fi 6 网卡,可 Ubuntu 20.04 默认的 5.4 内核压根不认识…

📰

3步搞定宏源证券官方网下载与API变更

3步搞定宏源证券官方网下载与API变更 版本升级后 API 全变了,是不是让你抓狂?以前那套 getQuote() 直接调用的代码,现在全报 404 Not Found ,或者返回的数据结构里字段名全换了。别急,这篇 一文搞懂…

📰

aiohttp 修复 `CookieJar.update_cookies()` 未复制用户传入的可变 `Morsel` 对象的缺陷解析

后端Web框架WebSocket 【免费下载链接】aiohttp Asynchronous HTTP client/server framework for asyncio and Python 项目地址: https://gitcode.com/gh_mirrors/ai/aiohttp 点击查看 免费下载 本篇文章围绕 aiohttp 变更日志条目 CHANGES/13637.bugfix.rst&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬