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的基本用法,到简单的封装,再到 ...
随机推荐
- 字符串、字节数组、流之间的相互转换以及文件MD5的计算
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace myMe ...
- maven---->配置,指令,插件,使用
maven是用于java的自动化构建工具. 1.下载:http://maven.apache.org/download.cgi 下载下面截图标红处的文件 然后直接解压可以得到文件夹,得到如下文件夹 不 ...
- FreeBSD之基本配置
1. 设置IP地址.网关ee /etc/rc.conf ifconfig_em0="inet 192.168.21.173 netmask 255.255.255.0" #设置 ...
- EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性
创建动态查询 想在项目中实现一个灵活的动态查询类,参考http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html和http://www.cnb ...
- EntityFramework的安装
关于EntityFramework在vs2012无法引用的问题 这段时间学习MVC,发现一个问题,我公司的电脑可以直接引用EntityFrameWork这个命名空间,但我家里面的电脑就不能直接引用,刚 ...
- HDOJ 1022 Train Problem
两个数组存进出顺序,如果不同进栈,相同出栈.
- java.lang.IllegalArgumentException: Service Intent must be explicit 解决办法
java.lang.IllegalArgumentException: Service Intent must be explicit 意思是服务必须得显式的调用 我之前是这样使用绑定Service的 ...
- PHP的几种输出方式
请写出echo.print_r.print.var_dump .die之间的区别 echo 只能输出字符串等单一数据 不能输出数据类型 不能输出数组等多种数据 print() 只能输出字符串等单一 ...
- HashMap的两种排序方式
Map<String, Integer> map = new HashMap<String, Integer>();map.put("d", 2);map. ...
- python记录_day30 多进程
1.什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础. 同一个程序执行两次,就会产生两个进程 ## 进程调度算 ...