body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

面向对象:

Noncopyable.h Thread.h
#ifndef __NONCOPYABLE_H__
#define __NONCOPYABLE_H__
#include<iostream>
using namespace std;
namespace meihao
{
        class Noncopyable
        {
                public:
                        Noncopyable(){};
                        ~Noncopyable(){};
                private:
                        Noncopyable(const Noncopyable&);
                        Noncopyable& operator=(const Noncopyable&);
        };
};
#endif 
#ifndef __THREAD_H__
#define __THREAD_H__
#include<iostream>
#include"Noncopyable.h"
#include<pthread.h>
using namespace std;
namespace meihao
{
        class Thread:private Noncopyable
        {
                public:
                        Thread();
                        void start();
                        void join();
                        virtual void run() = 0;
                        virtual ~Thread();
                        static void* threadFunc(void*);
                private:
                        pthread_t _pthId;
                        bool _isRunning;
        };
};
#endif
MutexLock.h Condition.h
#ifndef __MUTEXLOCK_H__
#define __MUTEXLOCK_H__
#include<iostream>
#include"Noncopyable.h"
#include<pthread.h>
using namespace std;
namespace meihao
{
        class MutexLock:public Noncopyable
        {
                public:
                        MutexLock();
                        ~MutexLock();
                        void lock();
                        void unlock();
                        pthread_mutex_t* getMutexPtr();
                private:
                        pthread_mutex_t _mutex;
        };
};
#endif
#ifndef __CONDITION_H__
#define __CONDITION_H__
#include<iostream>
#include"MutexLock.h"
#include"Noncopyable.h"
using namespace std;
namespace meihao
{
        class Condition:private Noncopyable
        {
                public:
                        Condition(MutexLock&);
                        ~Condition();
                        void wait();
                        void notify();
                        void notifyall();
                private:
                        pthread_cond_t _cond;
                        MutexLock& _mutex;
        };
};
#endif
Buffer.h Task.h
#ifndef __BUFFER_H__
#define __BUFFER_H__
#include<iostream>
#include"MutexLock.h"
#include"Condition.h"
#include"Task.h"
#include<queue>
using namespace std;
namespace meihao
{
        typedef Task* DataType;
        class Buffer:private Noncopyable
        {
                public:
                        Buffer(int);
                        void push(DataType);
                        DataType pop();
                        void wakeupEmpty();  // 唤醒所有等待队列不为空的线程
                        bool full();
                        bool empty();
                private:
                        MutexLock _mutex;
                        Condition _notFull;
                        Condition _notEmpty;
                        int _queSize;
                        queue<DataType> _que;
                        bool _flag;
        };
};
#endif
#ifndef __TASK_H__
#define __TASK_H__
#include<iostream>
using namespace std;
namespace meihao
{
        class Task
        {
                public:
                        virtual void process() = 0;  // 线程池里面的线程具体要做的任务
        };
};
#endif
Threadpool.h ThreadpoolThread.h
#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__
#include<iostream>
#include"Noncopyable.h"
#include"Task.h"
#include"Buffer.h"
#include<vector>
#include"Thread.h"
using namespace std;
namespace meihao
{
        class Threadpool:private Noncopyable
        {
                public:
                        Threadpool(int,int);
                        void start();
                        void stop();
                        void addTask(Task*);
                        Task* getTask();
                        void threadFunc();
                private:
                        int _threadNum;
                        vector<Thread*> _threadsVec;  // 存放线程池里面的所有线程
                        int _bufSize;
                        Buffer _buf;  // 缓冲区用来存放任务,到时候线程池从里面取走一个任务执行
                        bool _isExit;
        };
};
#endif
#ifndef __THREADPOOLTHREAD_H__
#define __THREADPOOLTHREAD_H__
#include<iostream>
#include"Thread.h"
#include"Threadpool.h"
using namespace std;
namespace meihao
{
        class Threadpoolthread:public Thread
        {
                public:
                Threadpoolthread(Threadpool& threadpool):_threadpool(threadpool){}
                void run()
                {
                        _threadpool.threadFunc();  // 继承的线程池线程内部实现的线程执行体方法
                        // 调用线程池的threadFunc方法,线程池的所有线程都去执行这个方法
                }
                private:
                        Threadpool& _threadpool;
        };
};
#endif
Thread.cpp MutexLock.cpp
#include"Thread.h"
#include<iostream>
using namespace std;
namespace meihao
{
        Thread::Thread():_pthId(0),_isRunning(false)
        {
        }
        void Thread::start()
        {
                pthread_create(&_pthId,NULL,&Thread::threadFunc,this);
                _isRunning = true;
        }
        void Thread::join()
        {
                if(_isRunning)
                        pthread_join(_pthId,NULL);
        }
        Thread::~Thread()
        {
                if(_isRunning)
                        pthread_detach(_pthId);
        }
        void* Thread::threadFunc(void* arg)
        {
                Thread* pthread = static_cast<Thread*> (arg);
                if(NULL!=pthread)
                        pthread->run();
        }
};
#include<iostream>
#include"MutexLock.h"
using namespace std;
namespace meihao
{
        MutexLock::MutexLock()
        {
                pthread_mutex_init(&_mutex,NULL);
        }
        MutexLock::~MutexLock()
        {
                pthread_mutex_destroy(&_mutex);
        }
        void MutexLock::lock()
        {
                pthread_mutex_lock(&_mutex);
        }
        void MutexLock::unlock()
        {
                pthread_mutex_unlock(&_mutex);
        }
        pthread_mutex_t* MutexLock::getMutexPtr()
        {
                return &_mutex;
        }
};
Condition.cpp Buffer.cpp
#include"Condition.h"
#include<iostream>
using namespace std;
namespace meihao
{
        Condition::Condition(MutexLock& mutex):_mutex(mutex)
        {
                pthread_cond_init(&_cond,NULL);
        }
        Condition::~Condition()
        {
                pthread_cond_destroy(&_cond);
        }
        void Condition::wait()
        {
                pthread_cond_wait(&_cond,_mutex.getMutexPtr());
        }
        void Condition::notify()
        {
                pthread_cond_signal(&_cond);
        }
        void Condition::notifyall()
        {
                pthread_cond_broadcast(&_cond);
        }
};
#include<iostream>
#include"Buffer.h"
using namespace std;
namespace meihao
{
        Buffer::Buffer(int size):_queSize(size)
                                                         ,_mutex()
                                                         ,_notFull(_mutex)
                                                         ,_notEmpty(_mutex)
                                                         ,_flag(true)   // 开始,标志位true,表示buffer正常运行
                                                                                        // 后面线程池要结束的时候会修改为false
        {
        }
        bool Buffer::full()
        {
                return _queSize == _que.size();
        }
        bool Buffer::empty()
        {
                return _que.size() == 0;
        }
        void Buffer::push(DataType elem)
        {
                _mutex.lock();
                while(full())
                {
                        _notFull.wait();  // 队列满,等待条件变量notFull满足
                        // 放到while里面是为了防止异常唤醒,唤醒的时候再次确认是否真的条件满足
                }
                _que.push(elem);
                _notEmpty.notify();
                _mutex.unlock();
        }
        DataType Buffer::pop()
        {
                _mutex.lock();
                while(_flag&&empty())  // flag如果为false表示线程池等待回收线程stop线程池
                {
                        _notEmpty.wait();
                }
                if(_flag)
                {
                        DataType tmp = _que.front();
                        _que.pop();
                        _notFull.notify();
                        _mutex.unlock();
                        return tmp;
                }
                else
                {
                        _mutex.unlock();
                        return NULL;
                }
        }
        void Buffer::wakeupEmpty()
        {
                _flag = false;
                _notEmpty.notifyall();  // 线程池在要关闭的时候会等待所有线程执行完挂在等待条件变量notEmpty上
                //这个时候直接唤醒所有等待的线程
        }
};
test.cpp Threadpool.cpp
#include<iostream>
#include"Threadpool.h"
#include<unistd.h>
using namespace std;
class MyTask:public meihao::Task
{
        public:
                void process()
                {
                        ::srand(time(NULL));
                        int num = ::rand()%100;
                        cout<<"produce a num:"<<num<<endl;
                }
};
int main()
{
        meihao::Threadpool threadpool(4,10);  // 定义一个线程池,里面有4个线程,去处理10个任务
        threadpool.start();
        meihao::Task* ptask = new MyTask();  // 定义一个具体的任务
        int cnt = 10;
        while(cnt--)
        {
                threadpool.addTask(ptask);  // 线程池中添加任务
                sleep(1);
        }
        threadpool.stop();
        return 0;
}
#include"Threadpool.h"
#include<iostream>
#include"Threadpoolthread.h"
#include<unistd.h>
using namespace std;
namespace meihao
{
        Threadpool::Threadpool(int threadNum,int bufSize):_threadNum(threadNum)
                              ,_bufSize(bufSize)                                                                    ,_buf(_bufSize)                                                                        ,_isExit(false)
        {
                _threadsVec.reserve(_threadNum);
        }
        void Threadpool::start()
        {
                for(int i=0;i<_threadNum;++i)
                {
                        Thread* pthread = new Threadpoolthread(*this);  // 创建指定个数个线程
                        _threadsVec.push_back(pthread);
                }
                for(auto& elem:_threadsVec)
                {
                        elem->start();  // 创造的线程开始启动
                }
        }
        void Threadpool::stop()
        {
                if(!_isExit)
                {
                        while(!_buf.empty())  // 如果缓冲池不空,也就是还有线程在执行
                        {
                                sleep(1);  // 等待所有线程执行完
                        }
                        // 线程全部执行完将会都挂在_buf里面的_notEmpty的条件变量上
                        _buf.wakeupEmpty();  // 唤醒所有等待_notEmpty的线程
                        // 这个函数设置flag = false; 所有等待在Buffer里面的pop函数
                        // 里的线程将全部返回NULL
                        _isExit = true;
                        for(auto& elem:_threadsVec)
                        {
                                elem->join();  // 回收所有线程资源
                                delete elem;
                        }
                }
        }
        void Threadpool::addTask(Task* task)
        {
                _buf.push(task);
        }
        Task* Threadpool::getTask()
        {
                return _buf.pop();
        }
        void Threadpool::threadFunc()
        {
                while(!_isExit)
                {
                        Task* task = getTask();
                        if(task)
                        {
                                task->process();
                        }
                }
        }
};

C++面向对象实现封装线程池的更多相关文章

  1. 使用C++11封装线程池ThreadPool

    读本文之前,请务必阅读: 使用C++11的function/bind组件封装Thread以及回调函数的使用 Linux组件封装(五)一个生产者消费者问题示例   线程池本质上是一个生产者消费者模型,所 ...

  2. c++简单线程池实现

    线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他 ...

  3. java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  4. C++线程池的实现

    线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他 ...

  5. Java线程池实现原理及其在美团业务中的实践

    本文转载自Java线程池实现原理及其在美团业务中的实践 导语 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供 ...

  6. Java线程池实现原理及其在美团业务中的实践(转)

    转自美团技术团队:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 随着计算机行业的飞速发展,摩尔定律逐 ...

  7. 面向对象的线程池Threadpool的封装

    线程池是一种多线程处理形式,预先创建好一定数量的线程,将其保存于一个容器中(如vector), 处理过程中将任务添加到队列,然后从容器中取出线程后自动启动这些任务,具体实现如下. 以下是UML图,展示 ...

  8. c++封装编写线程池

    在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编 ...

  9. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

随机推荐

  1. mui 配置底部tab切换方式以模板的方式访问

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. spring cloud: 关闭ribbon负载均衡

    spring cloud: 关闭ribbon负载均衡 1.eureka服务 2.2个user服务:7900/7901 3,movie服务 movie服务去请求 user的用户信息,而此时只想请求790 ...

  3. 【转】 strrchr()函数---C语言

    转自:https://baike.baidu.com/item/strrchr/4621437?fr=aladdin   函数名称: strrchr 函数原型:char *strrchr(const ...

  4. English trip V1 - B 15. Giving Personal Information 提供个人信息 Teacher:Solo Key: Do/Does

    In this lesson you will learn to answer simple questions about yourself.  本节课讲学到回答关于自己的一些简单问题 课上内容(L ...

  5. 使用getCurrentPosition方法实时获取当前Geolocation信息(附源码文件)--html5、JavaScript

    使用getCurrentPosition方法实时获取当前Geolocation信息: 1.getCurrentPosition方法的使用 navigator.geolocation.getCurren ...

  6. 20170822xlVBA ExportCellPhone

    Public Sub GetCellPhone() Dim CellPhone As String Dim Arr As Variant Dim Brr As Variant Dim n As Lon ...

  7. 关于Androidstudio无法获取到所有的SDk版本,需要挂国内镜像的问题

    由于墙的原因 我们在使用AndroidStudio的时候SDK Manager无法获取到所有的版本 需要我们设置下使用国内的镜像 ****首先打开Android SDK Manager  然后按照如图 ...

  8. Android -------- MVC,MVP 和 MVVM 架构设计模式

    MVC(Model-View-Controller)是最常见的软件架构之一,业界有着广泛应用.它本身很容易理解,但是要讲清楚,它与衍生的 MVP 和 MVVM 架构的区别就不容易了. 一.MVC MV ...

  9. Windows下如何使用Heroku

    1. 安装 进入https://devcenter.heroku.com/articles/heroku-cli#windows,选择对应版本安装 安装后使用heroku -v可检查版本号 2. 登陆 ...

  10. Sonya and Matrix CodeForces - 1004D (数学,构造)

    http://codeforces.com/contest/1004/problem/D 题意:网格图给定到中心点的曼哈顿距离数组, 求该图n,m及中心点位置 首先可以观察到距离最大值mx一定在某个角 ...