C++ 实现半同步半异步线程池

这段代码实现了一个基于C++的线程池,使用了pthread库来管理线程。线程池包含任务队列,可以动态调整线程数量,根据任务数量和线程空闲状态来创建或销毁线程。任务通过回调函数和参数传递,支持添加和删除任务。测试用例展示了如何向线程池添加任务并等待完成。
摘要由CSDN通过智能技术生成

半同步半异步线程池


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(&notEmpty,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(&notEmpty);
    }
    if(taskQ) delete taskQ;
    if(threadIDs) delete []threadIDs;
    pthread_mutex_destroy(&mutexpool);
    pthread_cond_destroy(&notEmpty);
}
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(&notEmpty);
}
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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VioletEvergarden丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值