基于单例模式懒汉实现方式的线程池
一、LockGuard.hpp
#pragma once
#include <iostream>
#include <pthread.h>
class Mutex
{
public:Mutex(pthread_mutex_t* lock_p=nullptr):_lock_p(lock_p){}~Mutex(){}void lock(){if(_lock_p){pthread_mutex_lock(_lock_p);}}void unlock(){if(_lock_p){pthread_mutex_unlock(_lock_p);}}
private:pthread_mutex_t* _lock_p;
};
class LockGuard
{
public:LockGuard(pthread_mutex_t* mutex):_mutex(mutex){_mutex.lock();}~LockGuard(){_mutex.unlock();}
private:Mutex _mutex;
};
二、Task.hpp
#pragma once
#include <iostream>
#include <functional>
#include <string>
class Task
{typedef std::function<int(int,int,char)> func_t;
public:Task(){}Task(int x,int y,char op,func_t func):_x(x),_y(y),_op(op),_callBack(func){}std::string operator()(){int result=_callBack(_x,_y,_op);char buffer[1024];snprintf(buffer,sizeof(buffer),"%d %c %d=%d",_x,_op,_y,result);return buffer;}std::string toTaskString(){char buffer[1024];snprintf(buffer,sizeof(buffer),"%d %c %d=?",_x,_op,_y);return buffer;}
private:int _x;int _y;char _op;func_t _callBack;
};const std::string oper = "+-*/%";
int myMath(int x, int y, char op)
{int result = 0;switch (op){case '+':result = x + y;break;case '-':result = x - y;break;case '*':result = x * y;break;case '/':{if (y == 0){std::cerr << "div zero error" << std::endl;result = -1;}elseresult = x / y;}break;case '%':{if (y == 0){std::cerr << "mod zero" << std::endl;result = -1;}elseresult = x % y;}break;default:std::cout<<"运算符输入有误"<<std::endl;break;}return result;
}
三、Thread.hpp
#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cassert>
namespace ThreadNs
{typedef std::function<void*(void*)> func_t;const int num = 1024;class Thread{private:static void* start_routine(void* args){Thread* _this=static_cast<Thread*>(args);return _this->callback();} void* callback(){return _func(_args);}public:Thread(){char nameBuffer[num];snprintf(nameBuffer,sizeof(nameBuffer),"thread-%d",threadNum++);_name=nameBuffer;}void start(func_t func,void* args=nullptr){_func=func;_args=args;int n=pthread_create(&_tid,nullptr,start_routine,this);assert(n==0);(void)n;}void join(){int n=pthread_join(_tid,nullptr);assert(n==0);(void)n;}std::string threadName(){return _name;}~Thread(){}private:std::string _name;func_t _func;void* _args;pthread_t _tid;static int threadNum;};int Thread::threadNum=1;
}
四、ThreadPool.hpp
#pragma once
#include <vector>
#include <queue>
#include <pthread.h>
#include <unistd.h>
#include <mutex>
#include "Thread.hpp"
#include "LockGuard.hpp"
using namespace ThreadNs;
const int gnum =5;template <class T>
class ThreadPool;template <class T>
struct ThreadData
{ThreadData(ThreadPool<T>* tp,const std::string& s):_threadPool(tp),_name(s){}ThreadPool<T>* _threadPool;std::string _name;
};
template <class T>
class ThreadPool
{
private:static void* handlerTask(void* args){ThreadData<T>* td=static_cast<ThreadData<T>*>(args);while(1){T t;{ LockGuard lockGuard(td->_threadPool->mutex());while(td->_threadPool->IsQueueEmpty()){td->_threadPool->ThreadWait();}t=td->_threadPool->Pop();}std::cout<<td->_name<<"已获取任务:"<<t.toTaskString()<<"处理结果是:"<<t()<<std::endl;}delete td;return nullptr;}ThreadPool(const int& num=gnum):_num(num){pthread_mutex_init(&_mutex,nullptr);pthread_cond_init(&_cond,nullptr);for(int i=0;i<_num;++i){_threads.push_back(new Thread());}}ThreadPool(const ThreadPool<T>&)=delete;ThreadPool<T>& operator=(const ThreadPool<T>&)=delete;public:void LockQueue() {pthread_mutex_lock(&_mutex);}void UnLockQueue() {pthread_mutex_unlock(&_mutex);}bool IsQueueEmpty(){return _taskQueue.empty();}void ThreadWait() {pthread_cond_wait(&_cond,&_mutex);}T Pop() {T t=_taskQueue.front();_taskQueue.pop();return t;} pthread_mutex_t* mutex(){return &_mutex;}
public: void run(){for(const auto& t:_threads){ThreadData<T>* td=new ThreadData<T>(this,t->threadName());t->start(handlerTask,(void*)td);std::cout<<t->threadName()<<"start..."<<std::endl;}}void push(const T& in){LockGuard lockGuard(&_mutex);_taskQueue.push(in);pthread_cond_signal(&_cond);std::cout<<"任务发送成功"<<std::endl;}~ThreadPool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);for(const auto& t:_threads){delete t;}}static ThreadPool<T>* getInstance(){if(nullptr==tp){_singletonLock.lock();if(nullptr==tp){tp=new ThreadPool<T>(); }_singletonLock.unlock();}return tp;}
private:int _num;std::vector<Thread*> _threads;std::queue<T> _taskQueue;pthread_mutex_t _mutex;pthread_cond_t _cond;static ThreadPool<T>* tp;static std::mutex _singletonLock;};
template <class T>
ThreadPool<T>* ThreadPool<T>::tp=nullptr;template <class T>
std::mutex ThreadPool<T>::_singletonLock;