线程池项目(1)

张开发
2026/4/4 3:55:40 15 分钟阅读
线程池项目(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 大危害创建/销毁成本高频繁的创建销毁消耗大量资源降低执行效率。内存占用大每个线程有独立栈空间大量线程会耗尽系统内存。上下文切换开销大线程切换需要保存/恢复状态过多线程可能导致系统空转。系统负载失控大量线程同时唤醒会导致瞬间负载过高甚至系统崩溃。核心结论CPU 密集型任务线程数应接近 CPU 核心数避免无效切换。IO 密集型任务线程数可适当高于核心数但仍需控制。线程池的优势核心问题线程创建销毁消耗性能实时创建销毁降低系统性能。线程池的解决方案预热启动时预先创建线程存入池中等待任务。复用任务到来时直接复用线程避免临时创建。归还任务完成后将线程归还线程池而非销毁。线程池的两种核心模式1.Fixed 模式固定线程池核心特征线程池中的线程数量固定。适用场景对性能稳定性要求高、任务执行时间相对固定的场景。2.Cached 模式缓存线程池/动态线程池核心特征线程池中的线程数量根据任务动态增长。适用场景业务量波动大、短时间内大量突发任务。维度Fixed 模式Cached 模式线程数量固定动态增长带阈值线程回收核心线程不回收非核心按需超时回收保留核心线程核心优势稳定低切换开销灵活适配流量资源利用率高适用场景稳定业务、CPU 密集型流量波动大、IO 密集型线程互斥解决资源竞争目标同一时间仅允许一个线程访问共享资源避免数据竞争。常用工具互斥锁mutex通过加锁/解锁实现独占访问。原子类型atomic无锁原子操作性能更高。线程通信解决线程协作目标线程间按约定顺序执行实现生产者-消费者等模型。常用工具条件变量condition_variable实现等待-通知机制通常与互斥锁一起使用。信号量semaphore通过计数器控制并发访问实现限流/同步。核心基础概念1.竞态条件定义多线程环境下代码执行结果依赖于线程调度顺序导致不一致的结果。本质原因共享资源的非原子操作被线程切换打断。2.临界区定义访问共享资源的代码段是竞态条件的根源。3.重入函数可重入函数多个线程或中断安全调用不会引发数据竞争或逻辑错误。要求不使用共享/全局状态仅依赖传入参数和栈上的局部变量。不可重入函数在调用未完成时再次调用会导致数据混乱。常见原因使用全局变量、静态变量等。线程同步工具1.条件变量 std::condition_variable作用让线程等待某个条件成立后继续执行。适用场景生产者-消费者问题。核心 APIwait(lock, predicate)等待条件成立。notify_one()唤醒一个等待线程。notify_all()唤醒所有等待线程。2.信号量 std::counting_semaphore / binary_semaphoreC20作用通过计数器控制有多少线程同时访问资源。核心 APIacquire()申请一个名额。release()释放一个名额。try_acquire()非阻塞方式尝试获取名额。线程的两种状态状态是否持有锁是否参与抢锁什么情况下会抢锁阻塞mutex否不抢锁持有锁的线程释放锁时等待condition variable否已释放不抢锁其他线程调用notify_one/notify_all后才抢

更多文章