半同步半异步线程池
TaskQueue.h
#pragma once
#include<queue>
#include<pthread.h>
using namespace std;
using callback=void (*)(void* arg);
//任务结构体
template <class T>
struct Task{
Task<T>(){
function =nullptr;
arg=nullptr;
}
Task<T>(callback f,void* arg){
this->arg=(T*)arg;
function=f;
}
callback function;
T *arg;
};
//任务队列
template <class T>
class TaskQueue{
public:
TaskQueue();
~TaskQueue();
void addTask(Task<T> task);//添加任务
void addTask(callback f,void* arg);
Task<T> takeTask();//取出一个任务
inline int taskNumber(){//获取当前任务个数
return m_taskQ.size();
}
private:
queue<Task<T>> m_taskQ;
pthread_mutex_t m_mutex;
};
TaskQueue.cpp
#include"TaskQueue.h"
template <class T>
TaskQueue<T>::TaskQueue(){
pthread_mutex_init(&m_mutex,NULL);
}
template <class T>
TaskQueue<T>::~TaskQueue(){
pthread_mutex_destroy(&m_mutex);
}
template <class T>
void TaskQueue<T>::addTask(Task<T> task){
pthread_mutex_lock(&m_mutex);
m_taskQ.push(task);
pthread_mutex_unlock(&m_mutex);
}
template <class T>
void TaskQueue<T>::addTask(callback f,void* arg){
pthread_mutex_lock(&m_mutex);
m_taskQ.push(Task<T>(f,arg));
pthread_mutex_unlock(&m_mutex);
}
template <class T>
Task<T> TaskQueue<T>::takeTask(){
Task<T> t;
pthread_mutex_lock(&m_mutex);
if(!m_taskQ.empty()){
t=m_taskQ.front();
m_taskQ.pop();
}
pthread_mutex_unlock(&m_mutex);
return t;
}
ThreadPool.h
#pragma once
#include "TaskQueue.h"
#include "TaskQueue.cpp"
template <class T>
class ThreadPool{
public:
ThreadPool(int min,int max);
~ThreadPool();
void addTask(Task<T> task);
int getBusyNum();
int getLiveNum();
private:
static void* worker(void* arg);
static void* manager(void* arg);
void threadExit();
private:
TaskQueue<T>* taskQ;
pthread_t managerID;//管理者线程
pthread_t *threadIDs;//工作的线程ID
int minNum,maxNum;//最大,最小线程数
int busyNum;//正在工作的线程
int liveNum;//存活的线程
int exitNum;//要销毁的线程个数
pthread_mutex_t mutexpool;//锁整个线程池
pthread_cond_t notEmpty;//任务队列是否为空
bool shutdown;//是否销毁线程池,是为1
};
ThreadPool.cpp
#include<iostream>
#include<string.h>
#include<string>
#include<unistd.h>
#include "ThreadPool.h"
using namespace std;
template <class T>
ThreadPool<T>::ThreadPool(int min, int max){
//实例化任务队列
do{
taskQ = new TaskQueue<T>;
threadIDs=new pthread_t[max];
if(threadIDs==nullptr){
cout<<"malloc threadIDs fail"<<endl;
break;
}
memset(threadIDs,0,sizeof(pthread_t)*max);
minNum=min;
maxNum=max;
busyNum=0;
liveNum=min;
exitNum=0;
if(pthread_mutex_init(&mutexpool,NULL)!=0||pthread_cond_init(¬Empty,NULL)!=0){
cout<<"init mutex failed"<<endl;
break;
}
shutdown =false;
//创建管理者线程
pthread_create(&managerID,NULL,manager,this);
for(int i=0;i<min;++i){
pthread_create(&threadIDs[i],NULL,worker,this);
}
return;
}while(0);
//释放资源
if(threadIDs) delete[] threadIDs;
if(taskQ) delete taskQ;
}
template <class T>
ThreadPool<T>::~ThreadPool(){
//关闭线程池
shutdown=true;
//阻塞回收管理者线程
pthread_join(managerID,NULL);
//唤醒阻塞的消费者线程
for(int i=0;i<liveNum;i++){
pthread_cond_signal(¬Empty);
}
if(taskQ) delete taskQ;
if(threadIDs) delete []threadIDs;
pthread_mutex_destroy(&mutexpool);
pthread_cond_destroy(¬Empty);
}
template <class T>
void* ThreadPool<T>::worker(void* arg){
ThreadPool* pool=static_cast<ThreadPool*>(arg);
while(true){
pthread_mutex_lock(&pool->mutexpool);
while(pool->taskQ->taskNumber()==0&&!pool->shutdown){
//阻塞工作线程
pthread_cond_wait(&pool->notEmpty,&pool->mutexpool);
//判断是否要销毁线程
if(pool->exitNum>0){
pool->exitNum--;
if(pool->liveNum>pool->minNum){
pool->liveNum--;
pthread_mutex_unlock(&pool->mutexpool);
pool->threadExit();
}
}
}
pool->busyNum++;
//判断线程池是否关闭
if(pool->shutdown){
pthread_mutex_unlock(&pool->mutexpool);
pool->threadExit();
}
//从任务队列取一个任务
Task<T> task=pool->taskQ->takeTask();
//解锁
pthread_mutex_unlock(&pool->mutexpool);
cout<<"thread "<< pthread_self()<<" start working..."<<endl;
task.function(task.arg);
delete task.arg;
task.arg=nullptr;
cout<<"thread "<< pthread_self()<<" end working..."<<endl;
pthread_mutex_lock(&pool->mutexpool);
pool->busyNum--;
pthread_mutex_unlock(&pool->mutexpool);
}
}
template <class T>
void* ThreadPool<T>::manager(void* arg){
ThreadPool* pool=static_cast<ThreadPool*>(arg);
while(!pool->shutdown){
//每隔三秒检测一次
sleep(3);
//取出线程池中任务的数量和当前线程数量
pthread_mutex_lock(&pool->mutexpool);
int queueSize=pool->taskQ->taskNumber();
int liveNum=pool->liveNum;
int busyNum=pool->busyNum;
pthread_mutex_unlock(&pool->mutexpool);
//添加线程
//任务个数>存活线程个数&&存活的个数<最大线程数
if(queueSize>liveNum&&liveNum<pool->maxNum){
pthread_mutex_lock(&pool->mutexpool);
int counter=0;
for(int i=0;i<pool->maxNum&&counter<2&&pool->liveNum<pool->maxNum;i++){
if(pool->threadIDs[i]==0){
pthread_create(&pool->threadIDs[i],NULL,worker,pool);
counter++;
pool->liveNum++;
}
}
pthread_mutex_unlock(&pool->mutexpool);
}
//销毁线程
//忙线程*2<存活的线程&&存活的线程>最小线程数
if(busyNum*2<liveNum&&liveNum<pool->minNum){
pthread_mutex_lock(&pool->mutexpool);
pool->exitNum=2;
pthread_mutex_unlock(&pool->mutexpool);
//让工作线程自杀
for(int i=0;i<2;i++){
pthread_cond_signal(&pool->notEmpty);
}
}
}
}
template <class T>
void ThreadPool<T>::threadExit(){
pthread_t tid=pthread_self();
for(int i=0;i<maxNum;++i){
if(threadIDs[i]==tid){
threadIDs[i]=0;
cout<<"threadExit() called, "<< tid <<" exiting..."<<endl;
break;
}
}
pthread_exit(NULL);
}
template <class T>
void ThreadPool<T>::addTask(Task<T> task){
if(shutdown){
pthread_mutex_unlock(&mutexpool);
return;
}
taskQ->addTask(task);
pthread_cond_signal(¬Empty);
}
template <class T>
int ThreadPool<T>::getBusyNum(){
pthread_mutex_lock(&mutexpool);
int busyNum=this->busyNum;
pthread_mutex_unlock(&mutexpool);
return busyNum;
}
template <class T>
int ThreadPool<T>::getLiveNum(){
pthread_mutex_lock(&mutexpool);
int liveNum=this->liveNum;
pthread_mutex_unlock(&mutexpool);
return liveNum;
}
主测试函数 test.cpp
#include "ThreadPool.h"
#include "ThreadPool.cpp"
#include<unistd.h>
#include<iostream>
void taskFunc(void* arg){
int num=*((int*)arg);
cout<<"thread "<<pthread_self()<<" is working ,number= "<<num<<endl;
sleep(1);
}
int main(){
ThreadPool<int> pool(3,10);
for(int i=0;i<100;i++){
int *num=new int(i);
pool.addTask(Task<int>(taskFunc,num));
}
sleep(20);
return 0;
}