线程池原理+具体实现

线程池

一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,即在程序初始化时,创建一定数量的线程(又最大限制),从任务队列中获取任务,进行处理

线程池=至少一个线程+任务队列

作用:
1.避免为大量请求创建线程,导致瞬间资源耗尽程序崩溃的问题
2.避免大量线程频繁创建销毁所带来的时间成本

线程池的应用场景:
1.需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线 程池技术是非常合适的。因为单个任务小,而任务数量巨大,但对于长时间的任 务,比如一个Telnet这样会话时间比线程的创建时间长的多的任务,线程池的优点就不明显了
2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用

线程池的实现:
1.创建固定数量的线程,创建线程安全的任务队列
2.循环从任务队列中获取任务对象,执行任务对象中的任务接口和数据

代码框架

//任务类
typrdef void(*handler_t)(int data)//函数指针
class Task{
     int data;            //要处理的数据
     handler_t_handle;    //处理数据的函数
     setdata(int data,handler_t func){
     _data=data;
     _handler=func;
     }
     run(){
     _handler(data);
     }
}
//线程池类
class threadpool{
     int thr_max;    //线程的最大个数
     std:queue<Task> _task_queue;     //实现线程安全的任务队列(同生产者与消费者模型)
     pthread_mutex_t_mutex;        //互斥锁
     pthread_cond_t _pro_cond;     //生产者队列
     pthread_cond_t _con_cond;    //消费者队列
     
     TaskPush(Task &t);     //入队列
     TaskPop(Task &t);      //出队列
     void *thr_start(void *arg);     //线程函数用来处理任务
}

简单实现

#include <iostream>
#include <queue>
#include <pthread.h>

typedef void (*handler_t)(int data);//定义函数指针
class Task
{
    public:
        void SetTask(int data, handler_t handler){//将数据和处理函数传入
            _data = data;
            _handler = handler;
        }
		//给线程池的所有线程提供统一的接口
        void Run(){
            _handler(_data);
        }
    private:
        int _data;
        handler_t _handler;
};

#define THR_MAX 5
class ThreadPool
{
    public:
	//构造函数
        ThreadPool(int max==THR_MAX) 
		    : _thr_max(max)
			,_cur_thr(max)
			,_quit_flag(false) 
		{	
            pthread_mutex_init(&_mutex, NULL);
            pthread_cond_init(&_con_cond, NULL);
            pthread_cond_init(&_pro_cond, NULL);
        }
        ~ThreadPool() {
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_con_cond);
            pthread_cond_destroy(&_pro_cond);
        }
		
		//创建线程
        bool PoolInit() {
            int ret;
            pthread_t tid;
            for (int i = 0; i < _thr_max; i++) {
                ret = pthread_create(&tid, NULL, thr_start,(void*)this);
                if (ret != 0) {
                    std::cerr << "thread create error\n";
                    return false;
                }
				
                pthread_detach(tid);//将退出的线程的资源自动回收
            }
            return true;
        }
		//入队任务
        bool TaskPush(Task &t) {
            QueueBlock();
            _task_queue.push(t);
            ConsumerWakeUp();//唤醒消费者
            QueueUnblock();
            return true;
        }
		//出队任务
        bool TaskPop(Task &t) {
			//获取队首任务并出队
            t = _task_queue.front();
            _task_queue.pop();
            return true;
        }
		//线程入口函数
        static void *thr_start(void *arg) {
            ThreadPool *pool = (ThreadPool*)arg;
			while(1){
                pool->QueueBlock();
			    //任务队列为空,等待在生产者队列
                while (pool->QueueIsEmpty()) {
                pool->ConsumerWait();
                }
                Task t;
                pool->TaskPop(t);
                pool->QueueUnblock();
			    //需要先解锁再处理任务,否则其他线程无法处理任务,丧失并发性
                t.Run();
			}
            return NULL;
        }
		
		//线程池的退出,等所有任务处理完毕才退出,不能直接return 0
		void PoolQuit(){
			QueueBlock();
			if(_quit_flag==false){
				_quit_flag==true;
			}
			QueueUnblock();
			while(_cur_thr>0){
				ConsumerWakeUp();
				
			}
		}
	public:
        void QueueBlock(){
			pthread_mutex_lock(&_mutex);
		}	
		void QueueUnblock(){
			pthread_mutex_unlock(&_mutex);
		}
		//线程陷入等待之前需要先判断用户是否要退出
		void ConsumerWait(){
			if(_quit_flag==true){
				_cur_thr--;
				pthread_mutex_unlock(&_mutex);
				pthread_exit(NULL);
			}
			pthread_cond_wait(&_con_cond,&_mutex);
		}
		void ConsumerWakeUp(){
			pthread_cond_signal(&_con_cond);
		}
		bool QueueIsEmpty(){
			return _task_queue.empty();
		}
    private:
        int _thr_max;//最大线程数量
        std::queue<Task> _task_queue;//任务队列
		bool _quit_flag;//设置一个标志,在flag为true时,所有线程被唤醒并退出
		int _cur_thr;//当前线程池的线程数量
        pthread_mutex_t _mutex;
        pthread_cond_t _pro_cond;
        pthread_cond_t _con_cond;
};

int main ()
{
	pool.poolQuit();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值