C++线程池实现

直接上代码

/*
    author:wcx
    date:2020/4/9
    task:声明工作结点,声明线程池类。
    name:ThreadPool.h
*/
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <iostream>
#include <string>
#include <queue>
#include <pthread.h>
#include <thread>
#include <mutex>
using namespace std;
namespace wcx{
    class Task{
    public:
        Task(void *args=nullptr,const string name=""):
            args(args),name(name){
            
        }
        ~Task()=default;
        virtual void run()=0;  //纯虚函数,必须被overwrite
    private:
        void *args;  //参数
        string name;
        Task(const Task &);
    };
   
   
   
    
    class ThreadPool{
    public:
        ThreadPool(int threadcnt);
        ThreadPool();
        int size(); //返回工作队列大小
        void start(); //开启线程池
        void stop();  //中止所有线程
        void addtask(Task *); //添加工作
    private:
        void createthread(); //创建对应线程
        void threadfunc(); //执行线程指向的函数
        Task *gettask(); //从等待队列拿出来一个然后执行
        
    private:
        // thread *threadhead; //整个线程队列
        vector<thread> threadqueue;
        int threadcnt;
        queue<Task*> taskqueue;
        // mutex mt;
        pthread_mutex_t mt;
        pthread_cond_t conlock;
        bool isrunning;
        ThreadPool(const ThreadPool &);
    };
}
#endif
/*
    author:wcx
    date:2020/4/9
    task:实现线程池类。
    name:ThreadPool.cpp
*/
//互斥量和条件变量用在哪: 互斥量用在对task队列的改动,条件变量用在取出task时候的唤醒。
#include "ThreadPool.h"

using namespace wcx;

ThreadPool::ThreadPool(int cnt){
    threadcnt=cnt;
}
ThreadPool::ThreadPool(){
    threadcnt=10;
}

//返回工作队列大小
int ThreadPool::size(){  
    pthread_mutex_lock(&mt);
    int t=taskqueue.size();
    pthread_mutex_unlock(&mt);
    return t;
}

//开启线程池
void ThreadPool::start(){ 
    isrunning=true;
    createthread();
}

//中止所有线程
void ThreadPool::stop(){
    //结束所有线程(等待所有线程的执行完),释放资源
    if(!isrunning) return;
    isrunning=false;
    pthread_cond_broadcast(&conlock);
    for(int i=0;i<threadqueue.size();i++){
        threadqueue[i].join();
    }
    cout<<"开始清理"<<endl;
    threadqueue.clear();
    pthread_mutex_destroy(&mt);
    pthread_cond_destroy(&conlock);
    return;
}


//从任务队列中取出头部,然后开始执行
void ThreadPool::threadfunc(){
    while(isrunning){  //只要线程开着,我会一直轮询
        Task *now=gettask();
        if(now==NULL){
            //返回NULL说明已经stop了,不然不会返回null。
            cout<<"线程离开"<<endl;
            break;
        }
        now->run();  //多态
    }
}


//创建threadnum数量的线程,用Malloc创建,可能存在问题
void ThreadPool::createthread(){
    pthread_mutex_init(&mt,NULL);
    pthread_cond_init(&conlock,NULL); //初始化锁变量
    threadqueue.resize(threadcnt);
    for(int i=0;i<threadcnt;i++){
        //出错原因,这个线程还没有运行完就被销毁了。
        (threadqueue[i])=thread(&ThreadPool::threadfunc,this);
    }
    return;
}

//从等待队列拿出来一个然后执行
Task* ThreadPool::gettask(){
    //条件变量等待唤醒
    Task *task=NULL;
    while(true){
        pthread_mutex_lock(&mt);
        while(isrunning&&taskqueue.empty()){
            pthread_cond_wait(&conlock,&mt); //有任务来了被唤醒,stop的时候也唤醒。
        }
        if(!isrunning){
            pthread_mutex_unlock(&mt);
            return task;
        }
        task=taskqueue.front();
        taskqueue.pop();
        pthread_mutex_unlock(&mt);
        return task;
    }

}     

//添加工作,唤醒线程
void ThreadPool::addtask(Task *t){
    pthread_mutex_lock(&mt);
    taskqueue.push(t);
    pthread_mutex_unlock(&mt);
    pthread_cond_signal(&conlock);
}
/*
    author:wcx
    date:2020/4/9
    task:实现线程池类。
    name:main.cpp
*/
#include "ThreadPool.h"
int cc=0;
mutex tt;
class Mytask:public wcx::Task{
public:
    void run(){
        tt.lock();
        cout<<++cc<<endl;
        cout<<"I'm running!!!"<<endl;
        tt.unlock();
        return;
    }
};
int main(){
    Mytask *obj=new Mytask();
    wcx::ThreadPool pool(10);
    pool.start();
    for(int i=1;i<=20;i++){
        pool.addtask(obj);
    }
    while(1){
        if(pool.size()==0){
            pool.stop();
            break;
        }
    }
    cout<<"运行结束"<<endl;
}

程序逻辑:
在这里插入图片描述这个代码是跨平台的,没有特殊的api,重在逻辑。
参考博客:
https://www.cnblogs.com/li-daphne/p/5583224.html
逻辑一致,这里采用了更方便的thread(c++11新特性),存储方式进行了改变。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值