C++面向对象实现封装线程池
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++面向对象实现封装线程池的更多相关文章
- 使用C++11封装线程池ThreadPool
读本文之前,请务必阅读: 使用C++11的function/bind组件封装Thread以及回调函数的使用 Linux组件封装(五)一个生产者消费者问题示例 线程池本质上是一个生产者消费者模型,所 ...
- c++简单线程池实现
线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他 ...
- java线程池及创建多少线程合适
java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...
- C++线程池的实现
线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他 ...
- Java线程池实现原理及其在美团业务中的实践
本文转载自Java线程池实现原理及其在美团业务中的实践 导语 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供 ...
- Java线程池实现原理及其在美团业务中的实践(转)
转自美团技术团队:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 随着计算机行业的飞速发展,摩尔定律逐 ...
- 面向对象的线程池Threadpool的封装
线程池是一种多线程处理形式,预先创建好一定数量的线程,将其保存于一个容器中(如vector), 处理过程中将任务添加到队列,然后从容器中取出线程后自动启动这些任务,具体实现如下. 以下是UML图,展示 ...
- c++封装编写线程池
在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编 ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
随机推荐
- mui 配置底部tab切换方式以模板的方式访问
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- spring cloud: 关闭ribbon负载均衡
spring cloud: 关闭ribbon负载均衡 1.eureka服务 2.2个user服务:7900/7901 3,movie服务 movie服务去请求 user的用户信息,而此时只想请求790 ...
- 【转】 strrchr()函数---C语言
转自:https://baike.baidu.com/item/strrchr/4621437?fr=aladdin 函数名称: strrchr 函数原型:char *strrchr(const ...
- 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 ...
- 使用getCurrentPosition方法实时获取当前Geolocation信息(附源码文件)--html5、JavaScript
使用getCurrentPosition方法实时获取当前Geolocation信息: 1.getCurrentPosition方法的使用 navigator.geolocation.getCurren ...
- 20170822xlVBA ExportCellPhone
Public Sub GetCellPhone() Dim CellPhone As String Dim Arr As Variant Dim Brr As Variant Dim n As Lon ...
- 关于Androidstudio无法获取到所有的SDk版本,需要挂国内镜像的问题
由于墙的原因 我们在使用AndroidStudio的时候SDK Manager无法获取到所有的版本 需要我们设置下使用国内的镜像 ****首先打开Android SDK Manager 然后按照如图 ...
- Android -------- MVC,MVP 和 MVVM 架构设计模式
MVC(Model-View-Controller)是最常见的软件架构之一,业界有着广泛应用.它本身很容易理解,但是要讲清楚,它与衍生的 MVP 和 MVVM 架构的区别就不容易了. 一.MVC MV ...
- Windows下如何使用Heroku
1. 安装 进入https://devcenter.heroku.com/articles/heroku-cli#windows,选择对应版本安装 安装后使用heroku -v可检查版本号 2. 登陆 ...
- Sonya and Matrix CodeForces - 1004D (数学,构造)
http://codeforces.com/contest/1004/problem/D 题意:网格图给定到中心点的曼哈顿距离数组, 求该图n,m及中心点位置 首先可以观察到距离最大值mx一定在某个角 ...