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. Windows 下 Redis 服务无法启动,错误 1067 进程意外终止解决方案

    1.检查端口是否被占用 2.修改 Windows 服务里的 Redis 服务为本地系统服务(修改方式见下文) 方法: 1.看系统日志 桌面计算机/此电脑(Win10名称)右键打开管理,或 Win+R ...

  2. spring cloud: Hystrix(一):简单使用

    在微服务架构中,我们将系统拆分为很多个服务,各个服务之间通过注册与订阅的方式相互依赖,由于各个服务都是在各自的进程中运行,就有可能由于网络原因或者服务自身的问题导致调用故障或延迟,随着服务的积压,可能 ...

  3. 一款好用的取色工具TakeColor

    简介:TakeColor,一款还算好用的取色软件,一个很小很简洁的exe文件,无需安装 使用:打开exe文件后,使用“Alt + C” 组合键即可在鼠标悬停的位置上获取到颜色值,可以获取HTML.RG ...

  4. LeetCode--003--无重复字符的最长子串(java)

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  5. RMQ 解决区间查询问题

    线段树写法不管,比较灵活.这里主要讨论DP实现. 其实单纯说RMQ解决的是区间最值查询是不准确的,只要满足一个区间的信息可以从它的覆盖区间获得(即[L,R]<=[L,r],[l,R] (l< ...

  6. java控制流

    目录 1.引用数据类型 2.流程控制语句 2.1 条件控制语句if 2.2 if语句与三元运算符的互换 2.3 循环语句 2.4 循环嵌套 2.5 跳转语句 2.6 选择结构switch 3.猜数字案 ...

  7. 『MXNet』第七弹_多GPU并行程序设计

    资料原文 一.概述思路 假设一台机器上有个GPU.给定需要训练的模型,每个GPU将分别独立维护一份完整的模型参数. 在模型训练的任意一次迭代中,给定一个小批量,我们将该批量中的样本划分成份并分给每个G ...

  8. spring boot(十六)使用Jenkins部署spring boot

    jenkins是devops神器,本篇文章介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署分为三个步骤: 第一步,jenkins安装 第二步,插件安装和配置 第 ...

  9. 突破本地离线存储5M限制的JS库localforage简介

    http://www.zhangxinxu.com/wordpress/2018/06/js-localforage-localstorage-indexdb/

  10. leetcode-algorithms-6 ZigZag Conversion

    leetcode-algorithms-6 ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag ...