线程池

一、什么是线程池

线程池=一个或多个线程+任务队列

       线程池是一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待

着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利

用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。

二、线程池的作用

1、防止过度消耗资源

2、.避免大量线程频繁创建销毁的成本

三、线程池使用场景

1. 需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适

的。因为单个任务小,而任务数量巨大,可以想象一个热门网站的点击次数。 但对于长时间的任务请求,线程池的优点就不明

显了。因为请求时间比线程的创建时间大多了。

2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。

 3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大

量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误。.

四、 如何创建一个线程池

1.思路:

创建一个任务类:包含一个任务处理函数

创建一个线程池:1. 创建固定数量线程池,循环从任务队列中获取任务对象。
                             2. 获取到任务对象后,执行任务对象中的任务接口。

//创建线程
 //创建线程安全的任务队列
 //提供任务入队出队接口,线程池初始化销毁接口

2.实例:

完成功能:线程实现两数相加

main.cc:

#include"thread_pool.hpp"

#define NUM 5

int add(int x,int y)
{
    return x+y;
}

int main()
{
    ThreadPool *tp=new ThreadPool(NUM);
    tp->InitThreadPool();

    int count=1;
    while(1)
    {
        Task t(count,count-1,add);//创建任务
        tp->AddTask(t);//任务处理

        count++;
    }
    return 0;
}

thread_pool.hpp:

  1 #ifndef __THREAD_POOL_HPP__
  2 #define __THREAD_POOL_HPP__
  3 
  4 #include<iostream>
  5 #include<queue>
  6 #include<pthread.h>
  7 #include<unistd.h>
  8 
  9 using namespace std;
 10 
 11 typedef int (*cal_t)(int,int);
 12 class Task{
 13     private:
 14         int x;
 15         int y;
 16         cal_t handler_task;//执行函数

 17         int z;
 18     public:
 19         Task(int x_,int y_,cal_t handler_task_)
 20             :x(x_),y(y_),handler_task(handler_task_)
 21         {}
 22         void Run()
 23         {
 24             z=handler_task(x,y);
 25         }
 26         void Show()
 27         {
 28             //for test
 29             cout<<"thread"<<pthread_self()<<"Handler Task don    e."<<"Result is:"<<z<<endl;
 30             sleep(1);
 31         }
 32         ~Task()
 33         {}
 34     };
 35 
 36 class ThreadPool{
 37     private:
 38         int thread_nums;//线程个数
 39         std::queue<Task> t_queue;//任务队列
 40         pthread_mutex_t lock;
 41         pthread_cond_t cond;
 42         bool is_stop;//设置停止
 43     private:
 44         static void *thread_routine(void *arg)
 45         {
 46             ThreadPool *tp=(ThreadPool*)arg;
 47             pthread_detach(pthread_self());
 48             for(;;){
 49                 tp->LockQueue();
 50                 while(tp->IsEmpty()){//没有任务时等待
 51                     tp->IdleThread();
 52                 }
 53             Task t=tp->GetTask();//获取任务
 54             tp->UnlockQueue();//
 55 
 56             t.Run();//处理任务
 57             t.Show();
 58             }
 59         }
 60 
 61         void NotifyOneThread()
 62         {
 63             pthread_cond_signal(&cond);
 64         }
 65 
 66         void NotifyAllThreads()
 67         {
 68             pthread_cond_broadcast(&cond);
 69         }
 70     public:
 71         ThreadPool(int num_)
 72         :thread_nums(num_)
 73         {}
 74 
 75         void InitThreadPool()
 76         {
 77             pthread_mutex_init(&lock,NULL);
 78             pthread_cond_init(&cond,NULL);
 79             int i=0;
 80             for(;i<thread_nums;++i)
 81                 {
 82                     pthread_t tid;
 83                     pthread_create(&tid,NULL,thread_routine,(    void*)this);
 84                 }
 85         }
 86 
 87         void LockQueue()
 88         {
 89             pthread_mutex_lock(&lock);
 90         }
 91 
 92         void UnlockQueue()
 93         {
 94             pthread_mutex_unlock(&lock);
 95         }
 96 
 97         bool IsEmpty()
 98         {
 99             return t_queue.size()==0?true:false;
100         }
101 
102         void IdleThread()
103         {
104             if(is_stop){
105                 UnlockQueue();
106                 thread_nums--;
107                 pthread_exit((void *)0);
108                 cout<<"pthread"<<pthread_self()<<"quit"<<endl    ;
109                 return;
110             }
111             pthread_cond_wait(&cond,&lock);
112         }
113 
114         void AddTask(Task &t)
115         {
116             LockQueue();
117             if(is_stop){
118                 UnlockQueue();
119                 return;
120             }
121             t_queue.push(t);
122             NotifyOneThread();
123             UnlockQueue();
124         }
125 
126         Task GetTask()
127         {
128             Task t=t_queue.front();
129             t_queue.pop();
130             return t;
131         }
132 
133         void Stop()
134         {
135             LockQueue();
136             is_stop=true;
137             UnlockQueue();
138             while(thread_nums>0){
139                 NotifyAllThreads();
140             }
141         }
142 
143         ~ThreadPool()
144         {
145            pthread_mutex_destroy(&lock);
146            pthread_cond_destroy(&cond);
147         }
148     };
149 
150 #endif

结果:

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值