【Linux】线程池封装与介绍

1. 线程池介绍

  之前我们实现了线程、互斥量、条件变量以及日志的封装,现在我们可以基于以上内容来封装一个线程池。

  线程池是一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器处理器内核、内存、网络sockets等的数量。

  线程池的应用场景:

需要大量的线程来完成任务,且完成任务的时间比较短。 比如WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象⼀个热门网站的点击次数。 但对于长时间的任务,比如⼀个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误。

  线程池的种类:

创建固定数量线程池,循环从任务队列中获取任务对象,获取到任务对象后,执行任务对象中的任务接口;浮动线程池,其他同上。

此处,我们选择固定线程个数的线程池。

【Linux】线程池封装与介绍

2. 线程池封装首先我们需要包含需要的头文件以及命名空间,线程池类中成员变量需要一把锁、条件变量、条件变量下等待的线程个数、存放线程的数组、线程总个数、存放任务的任务队列以及线程池是否在运行的状态表示:代码语言:JavaScript代码运行次数:0运行复制

#include <iostream>#include <string>#include <queue>#include <vector>#include <memory>#include "Log.hpp"#include "Mutex.hpp"#include "Cond.hpp"#include "Thread.hpp"namespace ThreadPoolModule{    using namespace LogModule;    using namespace MutexModule;    using namespace CondModule;    using namespace ThreadModule;    using thread_t = std::shared_ptr<Thread>;    const static int gthreadnum = 10;    template <typename T>    class ThreadPool    {    private:        int _threadnum; // 线程个数        Mutex _mutex;        Cond _cond;        int _waitnum;        std::vector<thread_t> _threads; // 存放线程        std::queue<T> _tasks;           // 任务队列        bool _isrunning;    };}

在线程池类的构造函数中我们就可以创建固定数量的线程并给每个线程绑定执行的方法:代码语言:javascript代码运行次数:0运行复制

template <typename T>    class ThreadPool    {    private:        bool IsEmpty() { return _tasks.empty(); }        void HandlerTask(std::string name)        {            LOG(LogLevel::INFO) << name << " HandlerTask...";            T task;            while (true)            {                {                LockGuard lockguard(_mutex);                while (IsEmpty() && _isrunning)                {                    ++_waitnum;                    _cond.Wait(_mutex);                    --_waitnum;                }                if(!_isrunning&&IsEmpty())//为了在退出之前处理完所有的任务                    break;                task = _tasks.front();                _tasks.pop();                }                //处理任务不需要加锁保护                task(name);                LOG(LogLevel::INFO) << name << " handled a task successfully...";            }            LOG(LogLevel::INFO) << name << " exit success...";        }    public:        // 是要有的,必须是私有的        ThreadPool(int threadnum = gthreadnum) : _threadnum(threadnum),                                                 _waitnum(0),                                                 _isrunning(false)        {            // 创建线程            for (int i = 0; i < _threadnum; i++)            {                _threads.emplace_back(std::make_shared<Thread>(std::bind(&ThreadPool::HandlerTask, this, std::placeholders::_1))); // HandlerTask是成员函数有this参数,所以不能直接传参需要绑定                LOG(LogLevel::INFO) << _threads.back()->Name() << "Create Success...";            }            LOG(LogLevel::INFO) << "ThreadPool Construct...";        }        ~ThreadPool()        {        }    private:        int _threadnum; // 线程个数        Mutex _mutex;        Cond _cond;        int _waitnum;        std::vector<thread_t> _threads; // 存放线程        std::queue<T> _tasks;           // 任务队列        bool _isrunning;    };}

如果不清楚线程类中函数与线程池中的函数接口之间是怎么相互调用的可以看看:

【Linux】线程池封装与介绍

线程Start、Stop与Wait:代码语言:javascript代码运行次数:0运行复制

        void Start()        {            if (_isrunning)                return;            _isrunning = true;            for (auto &thread : _threads)            {                thread->Start();                LOG(LogLevel::INFO) << thread->Name() << " Start Success...";            }        }        void Stop()        {            LockGuard lockguard(_mutex);            if(_isrunning)            {                // 3. 不能在入任务了                _isrunning = false; // 不工作                // 1. 让线程自己退出(要唤醒) && // 2. 历史的任务被处理完了                if(_waitnum>0)                    _cond.NotifyAll();            }        }        void Wait()        {            for (auto &thread : _threads)            {                thread->Join();                LOG(LogLevel::INFO) << thread->Name() << "Wait Success...";            }        }

线程池处理任务在上述HandlerTask中,我们还需要线程池插入新任务的方法:代码语言:javascript代码运行次数:0运行复制

bool Enqueue(const T &in)        {            // 插入任务            LockGuard lockguard(_mutex);            if (!_isrunning)                return false;            _tasks.push(in);            if (_waitnum > 0)                _cond.Notify();            return true;        }

完整实现代码语言:javascript代码运行次数:0运行复制

#pragma once#include #include #include #include #include #include "Log.hpp"#include "Mutex.hpp"#include "Cond.hpp"#include "Thread.hpp"namespace ThreadPoolModule{    using namespace LogModule;    using namespace MutexModule;    using namespace CondModule;    using namespace ThreadModule;    using thread_t = std::shared_ptr;    const static int gthreadnum = 10;    template     class ThreadPool    {    private:        bool IsEmpty() { return _tasks.empty(); }        void HandlerTask(std::string name)        {            LOG(LogLevel::INFO) << name << " HandlerTask...";            T task;            while (true)            {                {                LockGuard lockguard(_mutex);                while (IsEmpty() && _isrunning)                {                    ++_waitnum;                    _cond.Wait(_mutex);                    --_waitnum;                }                if(!_isrunning&&IsEmpty())                    break;                task = _tasks.front();                _tasks.pop();                }                //处理任务不需要加锁保护                task(name);                LOG(LogLevel::INFO) << name << " handled a task successfully...";            }            LOG(LogLevel::INFO) << name << " exit success...";        }    public:        // 是要有的,必须是私有的        ThreadPool(int threadnum = gthreadnum) : _threadnum(threadnum),                                                 _waitnum(0),                                                 _isrunning(false)        {            // 创建线程            for (int i = 0; i < _threadnum; i++)            {                _threads.emplace_back(std::make_shared(std::bind(&ThreadPool::HandlerTask, this, std::placeholders::_1))); // HandlerTask是成员函数有this参数,所以不能直接传参需要绑定                LOG(LogLevel::INFO) << _threads.back()->Name() << "Create Success...";            }            LOG(LogLevel::INFO) << "ThreadPool Construct...";        }        void Start()        {            if (_isrunning)                return;            _isrunning = true;            for (auto &thread : _threads)            {                thread->Start();                LOG(LogLevel::INFO) << thread->Name() << " Start Success...";            }        }        void Stop()        {            LockGuard lockguard(_mutex);            if(_isrunning)            {                // 3. 不能在入任务了                _isrunning = false; // 不工作                // 1. 让线程自己退出(要唤醒) && // 2. 历史的任务被处理完了                if(_waitnum>0)                    _cond.NotifyAll();            }        }        void Wait()        {            for (auto &thread : _threads)            {                thread->Join();                LOG(LogLevel::INFO) << thread->Name() << "Wait Success...";            }        }        bool Enqueue(const T &in)        {            // 插入任务            LockGuard lockguard(_mutex);            if (!_isrunning)                return false;            _tasks.push(in);            if (_waitnum > 0)                _cond.Notify();            return true;        }        ~ThreadPool()        {        }    private:        int _threadnum; // 线程个数        Mutex _mutex;        Cond _cond;        int _waitnum;        std::vector _threads; // 存放线程        std::queue _tasks;           // 任务队列        bool _isrunning;    };}

测试函数如下:

任务函数:

代码语言:javascript代码运行次数:0运行复制

#pragma once#include <iostream>#include <string>#include <functional>#include "Log.hpp"using namespace LogModule;using task_t = std::function<void(std::string name)>;void Push(std::string name){    LOG(LogLevel::DEBUG) << "我是一个推送数据到服务器的一个任务, 我正在被执行" << "[" << name << "]";}

main函数:

代码语言:javascript代码运行次数:0运行复制

#include "ThreadPool.hpp"#include"Task.hpp"using namespace ThreadPoolModule;int main(){    ENABLE_CONSOLE_LOG_STRATEGY();    // ENABLE_FILE_LOG_STRATEGY();    std::unique_ptr<ThreadPool<task_t>> tp = std::make_unique<ThreadPool<task_t>>();    tp->Start();    int cnt = 10;    char c;    while (cnt)    {        tp->Enqueue(Push);         cnt--;        sleep(1);    }    tp->Stop();    sleep(3);    tp->Wait();    return 0;}

结果如下:代码语言:javascript代码运行次数:0运行复制

./thread_pool [2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-1Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-2Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-3Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-4Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-5Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-6Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-7Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-8Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-9Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [68] - Thread-10Create Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [70] - ThreadPool Construct...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-1 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-2 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-3 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-4 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-5 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-6 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-7 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-8 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-9 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [81] - Thread-10 Start Success...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-7 HandlerTask...[2025-02-04 09:54:51 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-7][2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-7 handled a task successfully...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-8 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-9 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-6 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-10 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-5 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-4 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-3 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-2 HandlerTask...[2025-02-04 09:54:51 ][INFO] [2360325] [ThreadPool.hpp] [30] - Thread-1 HandlerTask...[2025-02-04 09:54:52 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-7][2025-02-04 09:54:52 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-7 handled a task successfully...[2025-02-04 09:54:53 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-8][2025-02-04 09:54:53 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-8 handled a task successfully...[2025-02-04 09:54:54 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-9][2025-02-04 09:54:54 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-9 handled a task successfully...[2025-02-04 09:54:55 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-6][2025-02-04 09:54:55 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-6 handled a task successfully...[2025-02-04 09:54:56 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-10][2025-02-04 09:54:56 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-10 handled a task successfully...[2025-02-04 09:54:57 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-5][2025-02-04 09:54:57 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-5 handled a task successfully...[2025-02-04 09:54:58 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-4][2025-02-04 09:54:58 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-4 handled a task successfully...[2025-02-04 09:54:59 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-3][2025-02-04 09:54:59 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-3 handled a task successfully...[2025-02-04 09:55:00 ][DEBUG] [2360325] [Task.hpp] [14] - 我是一个推送数据到服务器的一个任务, 我正在被执行[Thread-2][2025-02-04 09:55:00 ][INFO] [2360325] [ThreadPool.hpp] [51] - Thread-2 handled a task successfully...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-7 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-8 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-9 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-6 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-10 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-5 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-4 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-3 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-2 exit success...[2025-02-04 09:55:01 ][INFO] [2360325] [ThreadPool.hpp] [54] - Thread-1 exit success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-1Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-2Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-3Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-4Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-5Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-6Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-7Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-8Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-9Wait Success...[2025-02-04 09:55:04 ][INFO] [2360325] [ThreadPool.hpp] [101] - Thread-10Wait Success...

3. 线程安全的单例模式单例模式的特点

  某些类, 只应该具有⼀个对象(实例), 就称之为单例。

  在很多服务器开发场景中, 经常需要让服务器加载很多的数据 (上百G) 到内存中. 此时往往要用一个单例的类来管理这些数据。

饿汉实现方式和懒汉实现方式

[洗碗的例子]

吃完饭, 立刻洗碗, 这种就是饿汉方式. 因为下一顿吃的时候可以立刻拿着碗就能吃饭.吃完饭, 先把碗放下, 然后下⼀顿饭用到这个碗了再洗碗, 就是懒汉方式.饿汉方式实现单例模式:代码语言:javascript代码运行次数:0运行复制

template <typename T>class Singleton {static T data;public:static T* GetInstance() {return &data;}};

懒汉方式实现单例模式:代码语言:javascript代码运行次数:0运行复制

template <typename T>class Singleton {   static T* inst;public:   static T* GetInstance() {   if (inst == NULL)    {   inst = new T();    }   return inst;   }};

懒汉方式实现单例模式(线程安全版本):代码语言:javascript代码运行次数:0运行复制

// 懒汉模式, 线程安全template <typename T>class Singleton {volatile static T* inst; // 需要设置 volatile 关键字, 否则可能被编译器优化.static std::mutex lock;public:static T* GetInstance() {if (inst == NULL) // 双重判定空指针, 降低锁冲突的概率, 提⾼性能.{ lock.lock(); // 使⽤互斥锁, 保证多线程情况下也只调⽤⼀次 new.if (inst == NULL) {inst = new T();}lock.unlock(); }return inst;}};

注意事项:

加锁解锁的位置双重 if 判定, 避免不必要的锁竞争volatile关键字防止过度优化4. 单例式线程池

  我们使用的是饿汉实现方式来实现单例线程池,首先我们需要创建静态全局的线程池指针以及锁:

代码语言:javascript代码运行次数:0运行复制

#include <iostream>#include <string>#include <queue>#include <vector>#include <memory>#include "Log.hpp"#include "Mutex.hpp"#include "Cond.hpp"#include "Thread.hpp"namespace ThreadPoolModule{    using namespace LogModule;    using namespace MutexModule;    using namespace CondModule;    using namespace ThreadModule;    using thread_t = std::shared_ptr<Thread>;    const static int gthreadnum = 10;    template <typename T>    class ThreadPool    {    private:        int _threadnum; // 线程个数        Mutex _mutex;        Cond _cond;        int _waitnum;        std::vector<thread_t> _threads; // 存放线程        std::queue<T> _tasks;           // 任务队列        bool _isrunning;// 添加单例模式static ThreadPool<T> *_instance;static Mutex _lock;};//在类外初始化template <typename T>ThreadPool<T> *ThreadPool<T>::_instance = nullptr;template <typename T>Mutex ThreadPool<T>::_lock;}

然后获取线程池单例函数:代码语言:javascript代码运行次数:0运行复制

static ThreadPool<T> *GetInstance()        {            if (_instance == nullptr)            {                LockGuard lockguard(_lock);                if (_instance == nullptr)                {                    _instance = new ThreadPool<T>();                    _instance->Start();                }            }            LOG(LogLevel::DEBUG) << "GetInstance success...";            return _instance;        }

最后将构造函数以及Start函数设为私有以及将赋值和拷贝构造禁用。完整实现代码语言:javascript代码运行次数:0运行复制

#pragma once#include #include #include #include #include #include "Log.hpp"#include "Mutex.hpp"#include "Cond.hpp"#include "Thread.hpp"namespace ThreadPoolModule{    using namespace LogModule;    using namespace MutexModule;    using namespace CondModule;    using namespace ThreadModule;    using thread_t = std::shared_ptr;    const static int gthreadnum = 10;    template     class ThreadPool    {    private:        // 是要有的,必须是私有的        ThreadPool(int threadnum = gthreadnum) : _threadnum(threadnum),                                                 _waitnum(0),                                                 _isrunning(false)        {            // 创建线程            for (int i = 0; i < _threadnum; i++)            {                _threads.emplace_back(std::make_shared(std::bind(&ThreadPool::HandlerTask, this, std::placeholders::_1))); // HandlerTask是成员函数有this参数,所以不能直接传参需要绑定                LOG(LogLevel::INFO) << _threads.back()->Name() << "Create Success...";            }            LOG(LogLevel::INFO) << "ThreadPool Construct...";        }        bool IsEmpty() { return _tasks.empty(); }        void HandlerTask(std::string name)        {            LOG(LogLevel::INFO) << name << " HandlerTask...";            T task;            while (true)            {                {                    LockGuard lockguard(_mutex);                    while (IsEmpty() && _isrunning)                    {                        ++_waitnum;                        _cond.Wait(_mutex);                        --_waitnum;                    }                    if (!_isrunning && IsEmpty())                        break;                    task = _tasks.front();                    _tasks.pop();                }                // 处理任务不需要加锁保护                task(name);                LOG(LogLevel::INFO) << name << " handled a task successfully...";            }            LOG(LogLevel::INFO) << name << " exit success...";        }        void Start()        {            if (_isrunning)                return;            _isrunning = true;            for (auto &thread : _threads)            {                thread->Start();                LOG(LogLevel::INFO) << thread->Name() << " Start Success...";            }        }        // 赋值、拷⻉禁⽤        ThreadPool &operator=(const ThreadPool &) = delete;        ThreadPool(const ThreadPool &) = delete;    public:        static ThreadPool<T> *GetInstance()        {            if (_instance == nullptr)            {                LockGuard lockguard(_lock);                if (_instance == nullptr)                {                    _instance = new ThreadPool<T>();                    _instance->Start();                }            }            LOG(LogLevel::DEBUG) << "GetInstance success...";            return _instance;        }        void Stop()        {            LockGuard lockguard(_mutex);            if (_isrunning)            {                // 3. 不能在入任务了                _isrunning = false; // 不工作                // 1. 让线程自己退出(要唤醒) && // 2. 历史的任务被处理完了                if (_waitnum > 0)                    _cond.NotifyAll();            }        }        void Wait()        {            for (auto &thread : _threads)            {                thread->Join();                LOG(LogLevel::INFO) << thread->Name() << "Wait Success...";            }        }        bool Enqueue(const T &in)        {            // 插入任务            LockGuard lockguard(_mutex);            if (!_isrunning)                return false;            _tasks.push(in);            if (_waitnum > 0)                _cond.Notify();            return true;        }        ~ThreadPool()        {        }    private:        int _threadnum; // 线程个数        Mutex _mutex;        Cond _cond;        int _waitnum;        std::vector _threads; // 存放线程        std::queue _tasks;           // 任务队列        bool _isrunning;        // 单例模式        static ThreadPool *_instance;        static Mutex _lock;    };    // 在类外初始化    template     ThreadPool *ThreadPool::_instance = nullptr;    template     Mutex ThreadPool::_lock;}

测试函数:代码语言:javascript代码运行次数:0运行复制

#include <iostream>#include <functional>#include <unistd.h>#include "ThreadPool.hpp"using namespace ThreadPoolModule;using task_t = std::function<void(std::string name)>;void DownLoad(std::string name){    std::cout << "this is a task" << std::endl;}int main(){    ENABLE_CONSOLE_LOG_STRATEGY();    int cnt = 10;    while (cnt)    {        ThreadPool<task_t>::GetInstance()->Enqueue(DownLoad);        sleep(1);        cnt--;    }    ThreadPool<task_t>::GetInstance()->Stop();    sleep(5);    ThreadPool<task_t>::GetInstance()->Wait();    return 0;}

结果如下:代码语言:javascript代码运行次数:0运行复制

tutu@hecs-16648:~/linux/ThreadPool$ ./thread_pool [2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-1Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-2Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-3Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-4Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-5Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-6Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-7Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-8Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-9Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [36] - Thread-10Create Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [38] - ThreadPool Construct...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-1 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-2 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-3 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-4 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-5 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-6 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-7 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-8 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-9 Start Success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [76] - Thread-10 Start Success...[2025-02-04 14:40:58 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-7 HandlerTask...this is a task[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-8 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-7 handled a task successfully...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-6 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-9 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-10 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-5 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-4 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-3 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-2 HandlerTask...[2025-02-04 14:40:58 ][INFO] [2368011] [ThreadPool.hpp] [43] - Thread-1 HandlerTask...[2025-02-04 14:40:59 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:40:59 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-8 handled a task successfully...[2025-02-04 14:41:00 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:00 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-7 handled a task successfully...[2025-02-04 14:41:01 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:01 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-6 handled a task successfully...[2025-02-04 14:41:02 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:02 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-9 handled a task successfully...[2025-02-04 14:41:03 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:03 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-10 handled a task successfully...[2025-02-04 14:41:04 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:04 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-5 handled a task successfully...[2025-02-04 14:41:05 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:05 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-4 handled a task successfully...[2025-02-04 14:41:06 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:06 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-3 handled a task successfully...[2025-02-04 14:41:07 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...this is a task[2025-02-04 14:41:07 ][INFO] [2368011] [ThreadPool.hpp] [64] - Thread-2 handled a task successfully...[2025-02-04 14:41:08 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-8 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-7 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-6 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-9 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-10 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-5 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-4 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-3 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-2 exit success...[2025-02-04 14:41:08 ][INFO] [2368011] [ThreadPool.hpp] [66] - Thread-1 exit success...[2025-02-04 14:41:13 ][DEBUG] [2368011] [ThreadPool.hpp] [95] - GetInstance success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-1Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-2Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-3Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-4Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-5Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-6Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-7Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-8Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-9Wait Success...[2025-02-04 14:41:13 ][INFO] [2368011] [ThreadPool.hpp] [116] - Thread-10Wait Success...

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享