简易线程池的实现

一.线程池

线程池:大量线程(数量存在上限)+线程安全的任务队列

T1(线程创建)+T2(任务处理)+T3(线程销毁) = T(任务处理总时间)

在一个任务处理的总时间中,若T1+T3所占用的时间占用大量的比例,也就意味着大量任务的处理中,资源被浪费在线程的创建和销毁中,这是不合理的.

因此产生了线程池,创建出大量线程(并不退出),而是不断将任务交给这些线程进行处理.

避免了大量线程创建/销毁所带来的时间成本.

注意: 线程池中线程的数量是有上限的,避免出现峰值压力,瞬间资源被耗尽导致程序崩溃的危险.

二.线程池的实现

线程池中任务队列节点应该包含两个元素:

  1. 要处理的数据
  2. 这个数据对应的处理方法

任务队列:

typedef void (*handler_t)(int);
 //任务类:包含数据(_fd)以及处理数据(handler_t)的方法
class ThreadTask{
    public:
    	//无参构造和带参构造
        ThreadTask(){}
        ThreadTask(int data,handler_t hander)
            :_data(data)
             ,_handler(hander){}
    	//设置任务:将数据以及处理数据的方法添加到线程任务当中
        void SetTask(int data,handler_t hander){
            _data = data;
            _handler = hander;
            return;
        }
    	//利用处理数据的方法处理数据
        void Run(){
            return _handler(_data);
        }
    private:
        int _data; //数据
        handler_t _handler;//处理数据的方法
};

线程池的实现:线程安全利用互斥锁和条件变量实现

#define THR_MAX 5  //创建线程的个数
#define QUE_MAX 10 //线程安全的任务队列的节点最大值
 
//线程池:
class ThreadPoll{
    public:
    	//初始化线程池:初始化互斥量和条件变量(保存线程安全),创建出线程,并且分离线程 
        ThreadPoll(int thr_max = THR_MAX,int que_max = QUE_MAX){
            pthread_mutex_init(&_mutex,NULL);
            pthread_cond_init(&_cond_pro,NULL);
            pthread_cond_init(&_cond_cus,NULL);
            int ret;
            pthread_t tid;
            for(int i = 0;i < thr_max;i++){
                ret = pthread_create(&tid,NULL,thr_start,this);
                if(ret != 0){
                    std::cout << "create thread error" << std::endl;
                    exit(-1);
                }
                pthread_detach(tid); //分离线程:不关心线程退出返回值 线程结束自动释放资源,不需要线程等待
            }
        }
    	//线程池析构:销毁条件变量以及互斥量
        ~ThreadPoll(){
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_cond_pro);
            pthread_cond_destroy(&_cond_cus);
        }
        //将任务添加至任务队列:
        bool TaskPush(const ThreadTask& task){
            pthread_mutex_lock(&_mutex); //互斥锁上锁
            while(_queue.size() == _capacity){ //当任务队列满时,生产者线程进行等待
                pthread_cond_wait(&_cond_pro,&_mutex);
            }
            _queue.push(task);
            pthread_mutex_unlock(&_mutex); //解锁      
            pthread_cond_signal(&_cond_cus); //唤醒消费者进行消费
            return true;
        }
 		//线程入口函数:线程的任务就是从任务队列中取出任务,然后用处理数据的方法处理数据
        static void* thr_start(void* arg){
            ThreadPoll* pool = (ThreadPoll*)arg;
            while(1){
                pthread_mutex_lock(&pool->_mutex);
                while(pool->_queue.empty()){
                    pthread_cond_wait(&pool->_cond_cus,&pool->_mutex);
                }
                ThreadTask task;
                task = pool->_queue.front();
                pool->_queue.pop();
                pthread_mutex_unlock(&pool->_mutex);
                pthread_cond_broadcast(&pool->_cond_pro); //唤醒所有被阻塞的生产者线程
                task.Run();//调用处理数据的方法处理数据
            }
            return NULL;
        }
    private:
        int _thread_max; //可创建线程的最大值
        int _capacity; //任务队列节点的最大值
        std::queue<ThreadTask> _queue; //存放任务的队列
        pthread_mutex_t _mutex;  //互斥锁
        pthread_cond_t _cond_pro; //生产者
        pthread_cond_t _cond_cus;  //消费者
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值