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

线程池项目(1)

推荐去看施磊老师的课程
需要课程或者代码的可以评论,看到会回复的,免费的

并发与并行

定义
  • 并发:多个线程在单核上轮流占用 CPU 时间片,物理上串行执行,但由于时间片较短,看起来像是同时执行。
  • 并行:多个线程在多核或多 CPU 上真正同时执行。

IO 密集型与 CPU 密集型

1. IO 密集型程序
  • 核心特征:程序大部分时间等待 IO 操作(网络、文件、数据库等)。
  • 运行状态:CPU 长期空闲,等待 IO 完成。
  • 适用结论:适合使用多线程。
  • 原理:IO 阻塞时,CPU 可以调度其他线程执行,充分利用空闲时间。
2. CPU 密集型程序
  • 核心特征:程序持续进行计算操作,几乎无 IO 等待。
  • 运行状态:CPU 长期满负荷运行。
  • 适用结论
    • 多核 CPU:适合多线程,可利用多核并行加速。
    • 单核 CPU:单线程更优。
  • 原因:多线程带来频繁的上下文切换开销,反而降低性能。

线程调度与上下文切换

核心概念
  • 上下文切换:操作系统暂停当前线程,保存其执行状态,再加载下一个线程的状态。
  • 调度开销:上下文切换会消耗 CPU 时间,可能导致缓存失效,从而影响性能。
关键结论
  • IO 密集型程序:多线程收益大,适合使用。
  • CPU 密集型程序
    • 单核 CPU:单线程最优。
    • 多核 CPU:线程数不宜过多,建议接近 CPU 核心数,避免过度调度。

创建过多线程的危害与线程池

线程过多的 4 大危害
  1. 创建/销毁成本高:频繁的创建销毁消耗大量资源,降低执行效率。
  2. 内存占用大:每个线程有独立栈空间,大量线程会耗尽系统内存。
  3. 上下文切换开销大:线程切换需要保存/恢复状态,过多线程可能导致系统空转。
  4. 系统负载失控:大量线程同时唤醒会导致瞬间负载过高,甚至系统崩溃。
核心结论
  • CPU 密集型任务:线程数应接近 CPU 核心数,避免无效切换。
  • IO 密集型任务:线程数可适当高于核心数,但仍需控制。
线程池的优势
  • 核心问题:线程创建销毁消耗性能,实时创建销毁降低系统性能。
  • 线程池的解决方案
    • 预热:启动时预先创建线程,存入池中等待任务。
    • 复用:任务到来时直接复用线程,避免临时创建。
    • 归还:任务完成后,将线程归还线程池,而非销毁。

线程池的两种核心模式

1.Fixed 模式(固定线程池)
  • 核心特征:线程池中的线程数量固定。
  • 适用场景:对性能稳定性要求高、任务执行时间相对固定的场景。
2.Cached 模式(缓存线程池/动态线程池)
  • 核心特征:线程池中的线程数量根据任务动态增长。
  • 适用场景:业务量波动大、短时间内大量突发任务。
维度Fixed 模式Cached 模式
线程数量固定动态增长,带阈值
线程回收核心线程不回收,非核心按需超时回收,保留核心线程
核心优势稳定,低切换开销灵活适配流量,资源利用率高
适用场景稳定业务、CPU 密集型流量波动大、IO 密集型

线程互斥(解决资源竞争)
  • 目标:同一时间仅允许一个线程访问共享资源,避免数据竞争。
  • 常用工具
    • 互斥锁(mutex):通过加锁/解锁实现独占访问。
    • 原子类型(atomic):无锁原子操作,性能更高。
线程通信(解决线程协作)
  • 目标:线程间按约定顺序执行,实现生产者-消费者等模型。
  • 常用工具
    • 条件变量(condition_variable):实现等待-通知机制,通常与互斥锁一起使用。
    • 信号量(semaphore):通过计数器控制并发访问,实现限流/同步。

核心基础概念

1.竞态条件
  • 定义:多线程环境下,代码执行结果依赖于线程调度顺序,导致不一致的结果。
  • 本质原因:共享资源的非原子操作被线程切换打断。
2.临界区
  • 定义:访问共享资源的代码段,是竞态条件的根源。
3.重入函数
  • 可重入函数:多个线程或中断安全调用,不会引发数据竞争或逻辑错误。
    • 要求:不使用共享/全局状态,仅依赖传入参数和栈上的局部变量。
  • 不可重入函数:在调用未完成时再次调用会导致数据混乱。
    • 常见原因:使用全局变量、静态变量等。

线程同步工具

1.条件变量 std::condition_variable
  • 作用:让线程等待某个条件成立后继续执行。
  • 适用场景:生产者-消费者问题。
  • 核心 API
    • wait(lock, predicate):等待条件成立。
    • notify_one():唤醒一个等待线程。
    • notify_all():唤醒所有等待线程。
2.信号量 std::counting_semaphore / binary_semaphore(C++20)
  • 作用:通过计数器控制有多少线程同时访问资源。
  • 核心 API
    • acquire():申请一个名额。
    • release():释放一个名额。
    • try_acquire():非阻塞方式尝试获取名额。

线程的两种状态

状态是否持有锁?是否参与抢锁?什么情况下会抢锁?
阻塞(mutex)不抢锁持有锁的线程释放锁时
等待(condition variable)否(已释放)不抢锁其他线程调用notify_one/notify_all后才抢
http://www.jsqmd.com/news/584474/

相关文章:

  • OpenClaw多通道告警:SecGPT-14B检测结果同步邮件与钉钉
  • 创建基础数据表后数据无法保存怎么排查_权限设置与回滚处理
  • 一个工科生的电机控制实验笔记
  • C++ 类和对象(下)核心总结
  • 如何用共享线程处理跨页面的数据同步冲突与锁定机制
  • OpenClaw备份与恢复:千问3.5-9B配置迁移完整流程
  • 月之暗面 Kimi 进阶:从长文本到 AI 搜索——最懂中国用户的AI助手
  • PregelProtocol——定义了“LangChain执行体“最小功能集
  • 【Web3】智能合约质量保障工程:从单元测试到 Gas 效能优化
  • Manus:中国AI Agent的破圈之作
  • LN2266 超小型 低电压启动 PWM 控制 升压 DC/DC 电压调整器
  • 【Java Stream 流:高效、优雅的集合操作 ✨】
  • 内网渗透零基础入门教程!小白也能轻松搞懂内网渗透基础知识点
  • MongoDB GridFS的fs.files集合越来越大怎么优化
  • Product Hunt 每日热榜 | 2026-04-03
  • 2026年比较好的砂浆生产线稳定供货厂家推荐 - 品牌宣传支持者
  • ESP32-S3驱动JW01二氧化碳传感器,供电踩坑实录(附完整Arduino代码)
  • OpenClaw资源监控方案:百川2-13B-4bits模型运行时的性能优化
  • 从 AI 助手到 ADT 自动化桥梁:全面解析 Vibing Steampunk 的定位、能力边界与典型使用场合
  • 分钱的艺术:为什么钱分下去了,团队反而有了怨气?
  • 【分布式技术】RustFS 非 Docker 部署完整指南:从单机到生产集群
  • 智力能效:Token之上的竞争
  • C# Avalonia 20 - WindowsMenu- 魔改Hyperlink - 使用例子
  • LLM 是怎么学习的?训练过程大揭秘
  • 避坑指南:清华镜像源安装GitLab时你可能遇到的5个EL版本问题
  • XSS漏洞解析
  • 第6章 数据类型转换-6.3 转换为布尔值
  • 【网络安全干货】黑客内网渗透零基础入门,超详细基础知识手把手教学
  • 【MATLAB源码-第407期】基于OFDM的低轨卫星通信系统中同步技术与链路鲁棒性增强研究,包含:定时同步、频偏估计、载波恢复等。
  • Iterator 与 fail-fast 机制:你不知道的细节