C++项目实战--线程池代码讲解

简介: C++项目实战--线程池代码讲解

先上代码:

#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <mutex>
#include <condition_variable>
#include <queue>
#include <thread>
#include <functional>
class ThreadPool {
public:
    explicit ThreadPool(size_t threadCount = 8): pool_(std::make_shared<Pool>()) {
            assert(threadCount > 0);    //断言
            for(size_t i = 0; i < threadCount; i++) {  //创建 threadCount个工作线程
                std::thread([pool = pool_] {    //创建线程  将pool_ 赋值给 pool
                    std::unique_lock<std::mutex> locker(pool->mtx); //创建一个锁
                    //工作线程的逻辑
                    while(true) {       //不断的去向工作队列请求
                        if(!pool->tasks.empty()) { //如果工作队列不为空
                            auto task = std::move(pool->tasks.front());//获取一个任务
                            pool->tasks.pop();  //队列弹出已经被获取的任务
                            locker.unlock();    //解锁
                            task();             //处理任务
                            locker.lock();      //上锁
                        } 
                        else if(pool->isClosed) break; //如果工作队列为空,并且池子已经关闭,退出
                        else pool->cond.wait(locker);  //如果工作队列为空并且线程池没有关闭,则设置该工作线程阻塞等待 条件变量-1
                    }
                }).detach();    //设置线程分离
            }
    }
    ThreadPool() = default;         //采用默认的构造函数
    ThreadPool(ThreadPool&&) = default;     //采用默认的拷贝构造函数
    ~ThreadPool() {
        if(static_cast<bool>(pool_)) {
            {
                std::lock_guard<std::mutex> locker(pool_->mtx);     //创建一个锁
                pool_->isClosed = true;             //关闭线程池
            }       
            pool_->cond.notify_all();               //唤醒线程池中所以的线程,线程最终就会进入  else if(pool->isClosed) break; 逻辑,最后退出
        }
    }
    template<class F>
    void AddTask(F&& task) {    //向线程池中添加任务
        {
            std::lock_guard<std::mutex> locker(pool_->mtx);  //创建一个锁
            pool_->tasks.emplace(std::forward<F>(task));     //向工作队列中插入一个任务
        }
        pool_->cond.notify_one();   //唤醒一个线程  条件变量+1 
    }
private:
    struct Pool {           
        std::mutex mtx;                 //互斥锁    
        std::condition_variable cond;  //条件变量
        bool isClosed;                 //线程池是否关闭
        std::queue<std::function<void()>> tasks; //工作队列
    };
    std::shared_ptr<Pool> pool_;        //定义一个 Pool指针
};
#endif //THREADPOOL_H

这段代码是通过c++14写的,我们主要看逻辑关系和实现的原理。

一般线程池的实现的模型:消费者生产者

既然是生产者消费者模型,就设计到了线程同步的问题。。。。

线程同步问题:互斥量,条件变量

我们把代码分为三个部分来看:

这一部分是线程池所需要的一些条件

将互斥锁、条件变量、线程池是否关闭的状态、工作队列封装到一起,然后通过智能指针(共享的)来操作管理这些条件

向生产者向工作队列中添加任务(主线程去完成),并设置唤醒

explicit:防止构造函数出现隐式转换。比如 A  a = 8,这样是不允许的

通过while不断让工作线程的请求工作队列,如果工作队列不为空,则获取一个任务并处理。如果工作队列为空并且线程池已经关闭,则直接跳出。如果工作队列不为空并且线程池没有关闭,则阻塞等待被唤醒。

使用线程池可以减少线程的销毁,而且如果不使用线程池的话,来一个客户端就创建一个线程。比如有1000,这样线程的创建、线程之间的调度也会耗费很多的系统资源,所以采用线程池使程序的效率更高。 线程池就是项目启动的时候,就先把线程池准备好。

相关文章
|
2月前
|
C++ Windows
应用程序无法正常启动(0xc0000005)?C++报错0xC0000005如何解决?使命召唤17频频出现闪退,错误代码0xC0000005(0x0)
简介: 本文介绍了Windows应用程序出现错误代码0xc0000005的解决方法,该错误多由C++运行库配置不一致或内存访问越界引起。提供包括统一运行库配置、调试排查及安装Visual C++运行库等解决方案,并附有修复工具下载链接。
1094 1
|
9月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
4月前
|
API 数据安全/隐私保护 C++
永久修改机器码工具, exe一机一码破解工具,软件机器码一键修改工具【c++代码】
程序实现了完整的机器码修改功能,包含进程查找、内存扫描、模式匹配和修改操作。代码使用
|
5月前
|
C++
爱心代码 C++
这段C++代码使用EasyX图形库生成动态爱心图案。程序通过数学公式绘制爱心形状,并以帧动画形式呈现渐变效果。运行时需安装EasyX库,教程链接:http://【EasyX图形库的安装和使用】https://www.bilibili.com/video/BV1Xv4y1p7z1。代码中定义了屏幕尺寸、颜色数组等参数,利用随机数与数学函数生成动态点位,模拟爱心扩散与收缩动画,最终实现流畅的视觉效果。
833 0
|
11月前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
445 3
|
12月前
|
供应链 安全 NoSQL
PHP 互斥锁:如何确保代码的线程安全?
在多线程和高并发环境中,确保代码段互斥执行至关重要。本文介绍了 PHP 互斥锁库 `wise-locksmith`,它提供多种锁机制(如文件锁、分布式锁等),有效解决线程安全问题,特别适用于电商平台库存管理等场景。通过 Composer 安装后,开发者可以利用该库确保在高并发下数据的一致性和安全性。
179 6
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
169 1
C++ 多线程之初识多线程
|
算法 安全 C++
提高C/C++代码的可读性
提高C/C++代码的可读性
262 4
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
815 7
|
消息中间件 存储 安全

热门文章

最新文章