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. vue element-ui 日期选择器组件 日期时间格式化

    vue element-ui 组件开发大大提高了我们的效率,但有时候并不能满足我们的需求,例如时间,日期组件: element-ui 日期返回的格式是这样的,看下图: 但我们要的是另一个格式 , 如下 ...

  2. Angular 学习笔记 ( 创建 library, 转换老旧的 library )

    更新 : 2018-10-28 不知道为什么在 ng 跑一直做不到 .d.ts 最后发现,如果有一个插件 propagating-hammerjs.ts 那么就在 root create 一个 pro ...

  3. linux 如何释放缓存

    操作: 同步 sync 释放所有缓存 echo 3 > /proc/sys/vm/drop_caches 原理: sync 将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node.已延迟的 ...

  4. English trip V1 - B 16. Giving Reasons 提供个人信息 Teacher:Lamb Key: Why/Because

    In this lesson you will learn how to give reasons for something you've done. 课上内容(Lesson) Why do peo ...

  5. 自己动手编写IPv4地址包含关系测试的小脚本

    工作中需要对地址包含关系进行测试,现有ipaddress标准库和IPy无法满足,于是自己动手编写小脚本,主要实现== , in, <等专用功能,其他功能可以后续用到再补充,例如迭代打印网段内所有 ...

  6. OSPF - 1,基础

    1,OSPF知识点a)在OSPF中,如果是环回口宣告进OSPF,不管宣告时配置的是多少位掩码,路由器收到的都是32位.(EIGRP配了多少位就收到多少位).好处:EIGRP中,在PING包发起时如果在 ...

  7. p1470 Longest Prefix

    原本就想到dp,可是是我的思路是在串的各个位置都遍历一次set,看dp[i-st[k]]是否为1且前length(st[k])是st[k].这样200000*200*10会超时.更好的办法是在i位取前 ...

  8. Confluence 6 设置一个空间主页

    当你创建一个空间的时候,Confluence 将会自动为你创建的空间新建一个主页.如果你的空间是从蓝图中创建,并且蓝图中已经有一个供使用的主页了,那么这个主页将会自动从蓝图中载入有用的宏和在蓝图中指定 ...

  9. Being a Good Boy in Spring Festival HDU - 1850

    桌子上有M堆扑克牌:每堆牌的数量分别为Ni(i=1…M):两人轮流进行:每走一步可以任意选择一堆并取走其中的任意张牌:桌子上的扑克全部取光,则游戏结束:最后一次取牌的人为胜者. 现在我们不想研究到底先 ...

  10. Spring缓存注解

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...