【Linux】---线程池

什么是线程池?

所有的池化技术,都可以看作一种缓冲区,举个生活中的例子,蓄水池、大坝之类。大家想想这些蓄水池的作用是什么?

而线程池就是组织一批线程,在适当时机,按分配顺序去依次完成到来的任务。

为什么有线程池?

  1. 线程过多会带来调度开销,进而影响缓存局部性和整体性能。
  2. 而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。
  3. 这避免了在处理短时间任务时创建与销毁线程的代价。(指PCB)
  4. 线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。

线程池的应用场景:

  1. 需要大量的线程来完成任务,且完成任务的时间比较短。
  2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
  3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.

模拟实现线程池

#pragma once 
#include<iostream>
#include<pthread.h>
#include<queue>
#include<unistd.h>

template <class T1>
class mask
{
  public:
    mask(){}

    mask(T1 a,T1 b)
      :data1(a),data2(b)
    {}

    T1 Add()
    {
      T1 rel=data1+data2;
      std::cout <<"thread is[" << pthread_self() << "] mask run ... done: base# " ;
      std::cout<<data1<<" + "<<data2<<" = "<<rel<<std::endl;
      return rel;
    }

  protected:
    T1 data1;
    T1 data2;
};

template <class T>
class pthread_pool
{
  public:
    pthread_pool(int maxnum=6,bool q=false)
      :_poolmax(maxnum),quit(q)
    {}

    ~pthread_pool()
    {
      pthread_mutex_destroy(&lock);
      pthread_cond_destroy(&empty);
    }

    void push(T& in)
    {
      lock_queue();
      pool.push(&in);
      unlock_queue();
      //notice_consumer();
      notice_all_consumer();
    }

    void get_rel(T& out)  //这里不再需要上锁,因为获取数据的地方在线程调用的Run里,线程已经在Run函数里上好锁排好队了。
    {
      //lock_queue();
      out=*pool.front();
      pool.pop();
      //unlock_queue();
    }

    static void* Run(void* arg)  //由于C++成员函数第一个参数是隐藏的this指针,不符合pthread_create的第三个函数指针的参数,所以定义为静态成员函数去掉this指针。同时传参传this指针,方便访问使用成员
    {
      pthread_pool* this_p=(pthread_pool*)arg;
      while(!this_p->quit)
      {
        usleep(2500);
        this_p->lock_queue();
        while(!this_p->quit && this_p->cond_empty())  //当线程池为空时,线程都在cond_empty这个条件变量和锁内部,成队列等待,
          //唤醒可以一群唤醒(惊群效应)pthread_cond_broadcast(),也可以一个一个唤醒pthread_cond_signal()
        {
          this_p->wait_consumer();
        }
        T m;
        if(!this_p->quit && !this_p->pool.empty())
        {
          this_p->get_rel(m);
        }
        this_p->unlock_queue();
        m.Add();
      }
      return;
    }

    void quit_pthread_pool()
    {
      if(!pool.empty())
      {
        std::cout<<"仍有任务在运行!  "<<std::endl;
        return ;
      }
      quit =true;
      notice_all_consumer();
    }

    void Init()
    {
      pthread_mutex_init(&lock,nullptr);
      pthread_cond_init(&empty,nullptr);
      pthread_t t;
      for(int i=0;i<_poolmax;i++)
      {
        pthread_create(&t,nullptr,Run,this);
      }
    }

  protected:
    std::queue<T*> pool;
    int _poolmax;
    pthread_mutex_t lock;
    pthread_cond_t empty;
    bool quit;

  private:
    void lock_queue()
    {
      pthread_mutex_lock(&lock);
    }

    void unlock_queue()
    {
      pthread_mutex_unlock(&lock);
    }

    bool cond_empty()
    {
      return pool.empty();
    }

    void wait_consumer()
    {
      pthread_cond_wait(&empty,&lock);
    }

    void notice_consumer()
    {
      pthread_cond_signal(&empty);
    }
    void  notice_all_consumer()
    {
      pthread_cond_broadcast(&empty);
    }
};
#include"pthread_pool.hpp"
#include<unistd.h>
using namespace std;

int main()
{
  pthread_pool<mask<int>> pp(5);
  pp.Init();

  int count=30;
  while(count--)
  {
    int left=random()%103;
    int right=random()%103;
    mask<int> m(left,right);
    cout<<left<<" + "<<right<<" =  ? "<<endl;
    pp.push(m);
    usleep(1250);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值