Linux 之 【多线程】(线程池、单例模式)
目录1.线程池概念优点工作流程代码实现总结2.单例模式概念特点两种实现方式饿汉模式懒汉方式线程安全的懒汉方式双重判空C11后的最简实现局部静态成员要点总结1.线程池概念线程池是一种池化技术通过预先创建一组线程重复利用线程执行多个任务避免频繁创建/销毁线程的开销本质以空间换时间——用内存预分配换取CPU调度的效率优点优势原理收益降低开销复用线程避免重复创建/销毁短任务场景性能提升10~100倍提高响应速度线程已就绪任务到达即执行无需等待线程创建延迟降低控制并发度线程数量上限固定防止资源耗尽系统更稳定任务管理任务队列缓冲平滑突发流量削峰填谷统一管理监控、调优、扩展集中化运维友好可观测性强解耦设计线程池与任务生产分离可根据性能和任务量动态调整线程数提高运行效率工作流程1. 初始化阶段 └── 预创建 corePoolSize 个工作线程全部阻塞在任务队列上 2. 任务提交阶段 └── 提交者生产者将任务封装成 Runnable/Task └── 任务队列.push(task) 3. 任务执行阶段 └── 工作线程消费者 ├── while(1) { ├── task 任务队列.pop() // 队列空则阻塞 ├── task.run() └── } 4. 扩容阶段动态线程池 └── 队列满 线程数 maxPoolSize → 创建新线程 5. 缩容阶段 └── 线程空闲超过 keepAliveTime → 销毁线程 6. 销毁阶段 └── shutdown()不再接受新任务执行完已有任务后退出 └── shutdownNow()立即停止所有任务返回未执行任务列表代码实现线程入口函数在类内定义线程入口函数时需要将其定义为静态成员函数不然就会有隐藏的this指针导致参数不匹配在start函数中传递 this 指针 作为入口函数的参数这样线程入口函数就可以调用类内成员了RAII锁class LockGuard { explicit LockGuard(pthread_mutex_t mutex) { pthread_mutex_lock(mutex); } ~LockGuard() { pthread_mutex_unlock(mutex); } };即使在锁内return或抛异常也会自动解锁杜绝了忘记解锁导致的死锁代码简洁不需要手动写unlock锁外执行任务{ LockGuard guard(pool-mutex_); task_ptr std::move(pool-tasks_.front()); pool-tasks_.pop(); } // ← 锁在这里释放 // 锁外执行耗时任务 if (task_ptr) { (*task_ptr)(); }锁持有时间从任务执行时间降到队列操作时间支持长任务不阻塞其他线程取任务。任务抛异常不会影响线程池状态智能指针管理任务生命周期std::queuestd::shared_ptrT tasks_; auto task_ptr std::make_sharedT(std::move(task));自动释放内存无需手动delete线程异常退出时未执行的任务自动释放还可以存储派生类任务此外双关机既可以保证保证数据一致性又可以用于紧急停止场景移动语义优化大对象拷贝的性能try、catch 保证异常安全的任务执行#pragma once #include iostream #include vector #include string #include queue #include memory #include atomic #include functional #include pthread.h #include unistd.h /** * brief 线程池 - 工业级实现 * * 核心特性 * - 优雅关机原子标志 条件变量广播唤醒 * - RAII资源管理LockGuard自动加解锁 * - 移动语义任务支持右值传递零拷贝优化 * - 任务生命周期智能指针管理自动释放 * - 异常安全RAII保证异常时资源不泄露 * * 线程安全是多生产者/多消费者 */ templateclass T class ThreadPool { public: /** * brief 构造函数 * param num 线程数量默认5 */ explicit ThreadPool(int num 5) : shutdown_(false) , thread_count_(num) { if (num 0) { throw std::invalid_argument(Thread count must be positive); } pthread_mutex_init(mutex_, nullptr); pthread_cond_init(cond_, nullptr); } /** * brief 禁止拷贝/移动 - 包含pthread句柄 */ ThreadPool(const ThreadPool) delete; ThreadPool operator(const ThreadPool) delete; ThreadPool(ThreadPool) delete; ThreadPool operator(ThreadPool) delete; /** * brief 析构函数 - 自动优雅关机 */ ~ThreadPool() { shutdown(); // 1. 唤醒所有线程并等待退出 pthread_mutex_destroy(mutex_); pthread_cond_destroy(cond_); } /** * brief 启动线程池 */ void start() { LockGuard guard(mutex_); if (!threads_.empty()) return; // 防止重复启动 for (int i 0; i thread_count_; i) { pthread_t tid; pthread_create(tid, nullptr, worker, this); threads_.emplace_back(tid); } } /** * brief 优雅关闭线程池 * * 1. 设置关机标志原子操作保证内存可见性 * 2. 广播唤醒所有等待线程 * 3. 等待所有线程执行完当前任务后退出 * 4. 清空任务队列由任务智能指针自动释放 */ void shutdown() { shutdown_.store(true); { LockGuard guard(mutex_); pthread_cond_broadcast(cond_); // 唤醒所有等待线程 } // 等待所有线程退出 for (pthread_t tid : threads_) { pthread_join(tid, nullptr); } threads_.clear(); } /** * brief 立即关闭线程池 * * 1. 设置关机标志 * 2. 广播唤醒所有线程 * 3. 清空任务队列未执行的任务将被销毁 */ void shutdownNow() { shutdown_.store(true); { LockGuard guard(mutex_); // 清空任务队列智能指针自动释放任务资源 while (!tasks_.empty()) { tasks_.pop(); } pthread_cond_broadcast(cond_); } for (pthread_t tid : threads_) { pthread_join(tid, nullptr); } threads_.clear(); } /** * brief 提交任务左值版本 * param task 任务对象 */ void push(const T task) { if (shutdown_.load()) return; // 使用智能指针管理任务生命周期 auto task_ptr std::make_sharedT(task); LockGuard guard(mutex_); tasks_.push(std::move(task_ptr)); pthread_cond_signal(cond_); // 唤醒一个工作线程 } /** * brief 提交任务右值版本移动语义优化 * param task 任务对象 */ void push(T task) { if (shutdown_.load()) return; // 移动构造任务零拷贝优化 auto task_ptr std::make_sharedT(std::move(task)); LockGuard guard(mutex_); tasks_.push(std::move(task_ptr)); pthread_cond_signal(cond_); } /** * brief 获取当前任务队列大小不精确仅供参考 */ size_t size() const { LockGuard guard(const_castpthread_mutex_t(mutex_)); return tasks_.size(); } /** * brief 线程池是否已关闭 */ bool isShutdown() const { return shutdown_.load(); } private: /** * brief RAII锁守卫 * * 优点异常安全自动解锁防止遗漏 * 原理构造加锁析构解锁 */ class LockGuard { public: explicit LockGuard(pthread_mutex_t mutex) : mutex_(mutex) { pthread_mutex_lock(mutex_); } ~LockGuard() { pthread_mutex_unlock(mutex_); } private: pthread_mutex_t mutex_; }; /** * brief 工作线程入口函数 * param arg 线程池对象指针 * return nullptr * * 核心逻辑 * 1. 检查关机标志决定是否退出 * 2. 等待任务队列非空条件变量 * 3. 取出任务智能指针 * 4. 在锁外执行任务减少锁持有时间 */ static void* worker(void* arg) { ThreadPool* pool static_castThreadPool*(arg); while (!pool-shutdown_.load()) { std::shared_ptrT task_ptr; { LockGuard guard(pool-mutex_); // while循环防止伪唤醒 while (pool-tasks_.empty() !pool-shutdown_.load()) { pthread_cond_wait(pool-cond_, pool-mutex_); } // 关机检查如果已关机且队列空线程退出 if (pool-shutdown_.load() pool-tasks_.empty()) { break; } // 取出任务移动语义避免拷贝 task_ptr std::move(pool-tasks_.front()); pool-tasks_.pop(); } // 解锁锁持有时间极短 //锁外执行任务 // 1. 减少锁竞争 // 2. 支持长任务不阻塞其他线程 // 3. 异常安全任务抛异常不影响线程池状态 if (task_ptr) { try { (*task_ptr)(); // 执行任务 } catch (const std::exception e) { std::cerr Task execution failed: e.what() std::endl; } catch (...) { std::cerr Task execution failed with unknown error std::endl; } } } return nullptr; } private: // 同步原语 pthread_mutex_t mutex_; // 互斥锁保护任务队列 pthread_cond_t cond_; // 条件变量任务队列非空等待 // 线程管理 std::vectorpthread_t threads_; // 线程ID列表 int thread_count_; // 线程数量 // 任务管理 std::queuestd::shared_ptrT tasks_; // 任务队列智能指针自动管理生命周期 std::atomicbool shutdown_; // 优雅关机标志原子操作内存可见性 };总结线程池 生产者消费者模型 池化技术生产者提交任务消费者执行任务队列缓冲任务池化复用线程——以空间换时间以控制换稳定线程池的作用与实现原理的简述线程池的作用是复用线程以降低开销、控制并发度。线程池通过复用预先创建的线程避免了频繁创建销毁的开销从而提升系统性能同时通过限制最大线程数防止资源耗尽在吞吐量和稳定性之间取得平衡实现上它包含一个预先创建的线程组和一个任务队列。利用‘互斥锁’保护队列的临界区利用‘条件变量’实现线程的等待与唤醒当队列空时线程休眠有任务时唤醒线程执行从而实现高效的生产者-消费者模型。2.单例模式概念单例模式是一种创建型设计模式确保一个类只有一个实例并提供一个全局访问点特点唯一性某个类只应该有一个对象实例全局访问提供统一的全局访问接口典型应用场景服务器加载大量数据上百G到内存时用单例类管理这些数据两种实现方式饿汉模式class Singleton { public: static Singleton getInstance() { return instance; } private: Singleton() default; Singleton(const Singleton) delete; Singleton operator(const Singleton) delete; static Singleton instance; }; Singleton Singleton::instance;特点程序加载时就创建实例类比吃完饭立刻洗碗下一顿直接可用优点实现简单线程安全缺点无论是否使用都会创建可能造成资源浪费懒汉方式class Singleton { public: // 线程不安全 static Singleton* getInstance() { if (instance nullptr) { instance new Singleton(); } return instance; } private: Singleton() default; Singleton(const Singleton) delete; Singleton operator(const Singleton) delete; static Singleton* instance; }; Singleton* Singleton::instance nullptr;特点首次使用时才创建实例类比吃完饭先放着下顿用时再洗核心思想延迟加载优化启动速度C11后的最简实现局部静态成员class Singleton { public: static Singleton getInstance() { static Singleton instance; return instance; } private: Singleton() default; Singleton(const Singleton) delete; Singleton operator(const Singleton) delete; };C11保证局部静态对象初始化的线程安全性代码简洁只需初始化一次不需要显式加锁要点总结构造函数私有化防止外部创建对象拷贝构造和赋值私有防止拷贝产生新对象静态成员/静态方法提供全局访问点延迟加载懒汉模式的核心优势优化启动速度线程安全多线程环境下保证单一实例双重判空提高性能的关键技术volatile防止指令重排序和优化问题

相关新闻

Angel 模型训练核心类 MLLearner 详解:train 接口、训练流程与自定义实现

Angel 模型训练核心类 MLLearner 详解:train 接口、训练流程与自定义实现

人工智能机器学习分布式训练图计算后端 【免费下载链接】angel A Flexible and Powerful Parameter Server for large-scale machine learning 项目地址: https://gitcode.com/gh_mirrors/an/angel 点击查看 免费下载 MLLearner 是 Angel(A Flexible an…

2026/10/12 13:05:42 阅读更多 →
毕夏AI降重降AIGC:一份“化验单”引发的科普实验

毕夏AI降重降AIGC:一份“化验单”引发的科普实验

毕夏AI官网:www.bixiaai.com 微信公众号搜一搜:毕夏AI官网 各位同学好。今天聊一个让我血压有点高的话题。 上个月有个学生发来一张截图。他的论文查重报告:重复率4.8%。漂亮。旁边是AIGC检测报告:疑似AI生成67%。导师批注两个…

2026/10/12 13:06:31 阅读更多 →
你论文里的“引用”正在替你说话:毕夏AI官网 www.bixiaai.com 期刊论文功能的“信号降噪”逻辑

你论文里的“引用”正在替你说话:毕夏AI官网 www.bixiaai.com 期刊论文功能的“信号降噪”逻辑

毕夏AI官网:www.bixiaai.com 微信公众号搜一搜:毕夏AI官网 学术界有一个几乎所有人都在经历、但很少有人正视的困境。 不是“写不出来”。而是——你引用的每一篇文献,都在替你向审稿人传递一个信号。 问题是,大多数研究者根本…

2026/10/14 14:31:52 阅读更多 →

最新新闻

AI高薪风口来袭!小白程序员如何抓住机遇,收藏这份学习指南?

AI高薪风口来袭!小白程序员如何抓住机遇,收藏这份学习指南?

文章主要介绍了AI行业的薪资现状,从实习生日薪5000元到年薪上亿,AI人才市场正在经历一场白热化的争夺战。文章指出,AI正在“入侵”每一个行业,人才缺口超过500万,普通人有机会分到一杯羹。文章建议普通人通过系统学习掌…

2026/10/14 21:14:53 阅读更多 →
大厂校招薪资大揭秘:小白程序员必看,收藏这份热门岗位薪资指南!

大厂校招薪资大揭秘:小白程序员必看,收藏这份热门岗位薪资指南!

本文汇总了字节跳动、腾讯、阿里巴巴等热门大厂校招薪资情况,涵盖前后端开发、AI/Agent方向、测开等岗位。数据来源于往届案例及公开信息,详细展示了不同级别薪资待遇及福利。文章提醒求职者在选择Offer时,不仅要关注总包,还要了解…

2026/10/14 21:14:53 阅读更多 →
如何快速上手cad-viewer:10分钟在浏览器中打开你的第一份DWG/DWG图纸

如何快速上手cad-viewer:10分钟在浏览器中打开你的第一份DWG/DWG图纸

前端3D渲染图形学 【免费下载链接】cad-viewer The world’s first fully web-based DXF/DWG viewer and editor that runs entirely in the browser — no backend server required. 项目地址: https://gitcode.com/gh_mirrors/cad/cad-viewer 点击查看 免费下载 …

2026/10/14 21:14:53 阅读更多 →
大模型高薪诱惑:年薪百万?小白必看收藏!

大模型高薪诱惑:年薪百万?小白必看收藏!

一篇顶会一作AIGC方向211本硕,某短视频大厂算法岗月入4.5万,实际年薪或超百万。但需注意,高薪并非保底,且薪资构成复杂,包括签字费、期权等。大厂算法岗普通档薪资为26k-36k,该岗位薪资远超普通水平&#x…

2026/10/14 21:14:53 阅读更多 →
AI工程师两大门派:传统算法与AI大模型应用开发,收藏这份入门指南!

AI工程师两大门派:传统算法与AI大模型应用开发,收藏这份入门指南!

文章介绍了AI领域的两大门派:传统算法工程师和AI大模型应用开发工程师。前者是“基建狂魔”,通过数学和编程解决实际问题,如精准推荐、最优路线规划等;后者是“场景魔术师”,利用现成大模型解决业务落地难题&#xff0…

2026/10/14 21:14:53 阅读更多 →
阿里云短信签名模板审核避坑指南与Python调用实战

阿里云短信签名模板审核避坑指南与Python调用实战

简介:本资源是一份面向Java开发者的企业级短信集成实战示例,聚焦阿里云短信服务(Dysmsapi)的快速接入与稳定调用,适用于用户注册验证、密码重置、订单通知等典型业务场景。压缩包共92个文件,含68个C#源码文…

2026/10/14 21:13:53 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →