1.降低资源消耗,复用已创建的线程来降低创建和销毁线程的消耗。
2.提高响应速度,任务到达时,可以不需要等待线程的创建立即执行。
3.提高线程的可管理性,使用线程池能够统一的分配、调优和监控。
#pragma once
#include
#include
#include
#include
#include
#include"Task.hpp"
#include"Thread.hpp"
#include"lockGuard.hpp"
const int N=6;
template
class ThreadPool
{
pthread_mutex_t* getlock()
{
return &_mutex;
}
void threadwait()
{
//挂起一个线程
pthread_cond_wait(&_cond,&_mutex);
}
void threadwakeup()
{
//唤醒一个线程
pthread_cond_signal(&_cond);
}
public:
ThreadPool(int num=N)
:_num(num)
{
pthread_mutex_init(&_mutex,nullptr);
pthread_cond_init(&_cond,nullptr);
}
~ThreadPool()
{
for(auto& e:_threads)
{
e.join();
}
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
bool isEmpty()
{
return _tasks.empty();
}
void init()
{
//创建线程
for(int i=1;i<=_num;++i)
//pthread_create(&_threads[i],nullptr,ThreadRoutine,this);
_threads.push_back(Thread(i,ThreadRoutine,this));
}
void start()
{
//线程启动
for(auto& e:_threads)
{
e.run();
}
}
void check()
{
for(auto& e:_threads)
{
std::cout<<"线程ID"<* tp=static_cast*>(args);
while(true)
{
//1.判断是否有任务
T t; //有->处理
{ //无->等待
lockGuard lock(tp->getlock());
//如果任务队列为空,则等待
while(tp->isEmpty())
{
tp->threadwait();
}
t=tp->poptask();//从共有区域拿到线程独立栈上;
}
t();//调用task类里面的仿函数处理任务
std::cout << "thread handler done, result: " << t.formatRes() << std::endl;
}
}
private:
std::vector _threads;
int _num;//线程池里有几个线程;
std::queue _tasks; // 使用STL的自动扩容的特性
pthread_mutex_t _mutex;
pthread_cond_t _cond;
};
#pragma once
#include
#include
class Task
{
public:
Task(){}
Task(int x,int y,char op):_x(x),_y(y),_op(op),_result(0),_exitCode(0) {}
int operator()()
{
switch(_op)
{
case '+':
_result=_x+_y;
break;
case '-':
_result=_x-_y;
break;
case '*':
_result=_x*_y;
break;
case '/':
{
if(_y==0)
_exitCode=-1;
else
_result=_x/_y;
}
break;
case '%':
{
if(_y==0)
_exitCode=-2;
else
_result=_x%_y;
}
break;
default:
break;
}
}
//任务
std::string formatArg()
{
return std::to_string(_x) + _op + std::to_string(_y) + "=?";
}
//任务处理结果
std::string formatRes()
{
return std::to_string(_result) + "(" + std::to_string(_exitCode)+ ")";
}
~Task() {}
private:
int _x;
int _y;
char _op;
int _result;
int _exitCode;
};
#pragma once
#include
#include
class Mutex//成员:加锁函数和解锁函数
{
public:
Mutex(pthread_mutex_t* pmutex):_pmutex(pmutex) {}
void lock()
{
pthread_mutex_lock(_pmutex);
}
void unlock()
{
pthread_mutex_unlock(_pmutex);
}
~Mutex(){}
private:
pthread_mutex_t* _pmutex;//需要传入一个互斥量(锁)的指针;
};
//对Mutex进行二次封装;
//创建该对象时自动加锁,析构时自动解锁;
class lockGuard
{
public:
lockGuard(pthread_mutex_t* pmutex):_mutex(pmutex)//利用锁的指针构建Mutex对象
{
_mutex.lock();
}
~lockGuard()
{
_mutex.unlock();
}
private:
Mutex _mutex;//类内创建对象
};
#pragma once
#include
#include
#include
class Thread
{
public:
typedef void* (*func_t) (void*);
typedef enum
{
NEW=0,
RUNNING,
EXITED
}ThreadStatus;
public:
//状态:new,running,exited
int status()
{
return _status;
}
//线程名
std::string threadname()
{
return _name;
}
//线程ID(共享库中的进程地址空间的虚拟地址)
pthread_t threadid()
{
if(_status==RUNNING)//线程已经被创建,线程id已经输入到成员变量_tid中;
return _tid;
else
{
return 0;
}
}
public:
//构造函数;
Thread(int num,func_t func,void* args)//num代表第几个线程
:_tid(0),
_status(NEW),
_func(func),
_args(args)
{
char name[128];
snprintf(name,sizeof(name),"thread-%d",num);
_name=name;
}
//析构函数
~Thread(){}
//静态成员函数不能访问类内所有成员,因为没有this指针;
static void* runHelper(void *args)
{
Thread* td=(Thread*)args;
(*td)();//调用仿函数执行线程的回调函数;
return nullptr;
}
void operator()()//仿函数
{
//如果函数指针不为空,则执行该函数指针指向的回调函数;
if(_func!=nullptr) _func(_args);
}
//创建线程
void run()
{
//因为runHelper函数必须只能有一个void*参数,所以runHelper函数在类内必须定义为static,这样才没有this指针;
int n=pthread_create(&_tid,nullptr,runHelper,this);
if(n!=0) return exit(1);//线程创建失败,那么直接退出进程;
_status=RUNNING;
}
//等待线程结束
void join()
{
int n=pthread_join(_tid,nullptr);
if(n!=0)
{
std::cerr<<"main thread join thread "<<_name<<" error "<
#include
#include
#include"ThreadPool.hpp"
using namespace std;
int main()
{
// unique_ptr < ThreadPool > tp(new ThreadPool(20));
// tp->init();
// tp->start();
// tp->check();
//实例化类,并且多次调用getinstance()函数;
printf("0X%x\n", ThreadPool::getinstance());
printf("0X%x\n", ThreadPool::getinstance());
printf("0X%x\n", ThreadPool::getinstance());
printf("0X%x\n", ThreadPool::getinstance());
printf("0X%x\n", ThreadPool::getinstance());
printf("0X%x\n", ThreadPool::getinstance());
while(true)
{
// 充当生产者, 从网络中读取数据,构建成为任务,推送给线程池
int x, y;
char op;
std::cout << "please Enter x> ";
std::cin >> x;
std::cout << "please Enter y> ";
std::cin >> y;
std::cout << "please Enter op(+-*/%)> ";
std::cin >> op;
Task t(x,y,op);
ThreadPool::getinstance()->pushtask(t); //单例对象也有可能在多线程场景中使用!
}
return 0;
}
ThreadPool:main.cc
g++ $^ -o $@ -std=c++11 -lpthread
.PHONY:clean
clean:
rm -f ThreadPool