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,这样线程的创建、线程之间的调度也会耗费很多的系统资源,所以采用线程池使程序的效率更高。 线程池就是项目启动的时候,就先把线程池准备好。

相关文章
|
7天前
|
算法 安全 C++
提高C/C++代码的可读性
提高C/C++代码的可读性
20 4
|
16天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
30 7
|
16天前
|
消息中间件 存储 安全
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
43 1
C++ 多线程之初识多线程
|
23天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
45 6
|
1月前
|
缓存 负载均衡 Java
c++写高性能的任务流线程池(万字详解!)
本文介绍了一种高性能的任务流线程池设计,涵盖多种优化机制。首先介绍了Work Steal机制,通过任务偷窃提高资源利用率。接着讨论了优先级任务,使不同优先级的任务得到合理调度。然后提出了缓存机制,通过环形缓存队列提升程序负载能力。Local Thread机制则通过预先创建线程减少创建和销毁线程的开销。Lock Free机制进一步减少了锁的竞争。容量动态调整机制根据任务负载动态调整线程数量。批量处理机制提高了任务处理效率。此外,还介绍了负载均衡、避免等待、预测优化、减少复制等策略。最后,任务组的设计便于管理和复用多任务。整体设计旨在提升线程池的性能和稳定性。
77 5
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
23 0
C++ 多线程之线程管理函数
|
1月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
29 0
Linux C/C++之线程基础
|
1月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
211 0
vsCode远程执行c和c++代码并操控linux服务器完整教程