加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

线程池 实现

发布时间:2023-02-02 10:57:58 所属栏目:Linux 来源:
导读:  线程池

  1. 线程池概念

  线程池:一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能. 而线程池维护着多个线程线程池linux,等待着管理者分配可并发执行的任务. 这避免了在
  线程池
 
  1. 线程池概念
 
  线程池:一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能. 而线程池维护着多个线程线程池linux,等待着管理者分配可并发执行的任务. 这避免了在处理短时间任务时创建与销毁线程的代价,线程池不仅能保证内核的充分利用,还能防止过分调度,可用的线程数量应该取决于可用的并发处理器,处理器内核,内存,网络socket数量.
 
  线程池的应用场景:
 
  需要大量的线程来完成任务,且任务完成的时间比较短,Web服务器完成网页请求这样的任务,使用线程池技术是非常合适的,因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数,但对于长时间的任务,线程池的任务就不明显了.对性能要求苛刻的应用,比如要求服务器迅速响应客户请求.接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用,突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大多数操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.
 
  线程池的示例:
 
  创建固定数量线程池,循环从任务队列中获取任务对象.获取到任务对象后,执行任务对象中的任务接口. 2. 线程池实现
 
  #pragma once
  #include
  #include
  #include
  #include
  #include
  #include "Log.hpp"
  using namespace std;
  int gThreadNum = 5;
  template<class T>
  class ThreadPool
  {
  public:
      ThreadPool(int threadNum = gThreadNum)
          : threadNum_(gThreadNum)
          , isStart_(false)
      {
          assert(threadNum_ > 0);
          pthread_mutex_init(&mutex_, nullptr);
          pthread_cond_init(&cond_, nullptr);
      }
      ~ThreadPool()
      {
          pthread_mutex_destroy(&mutex_);
          pthread_cond_destroy(&cond_);
      }
      static void* threadRoutine(void* args)
      {
          pthread_detach(pthread_self());
          ThreadPool<T>* tp = static_cast<ThreadPool<T>* >(args);
          prctl(PR_SET_NAME, "follower");
          while(1)
          {
              tp->lockQueue();
              //如果没任务就wait
              while(!tp->haveTask())
              {
                  tp->waitForTask();
              }
              //这个任务被一个线程执行
              T t = tp->pop();
              tp->unlockQueue();
              int one, two;
              char oper;
              t.get(&one, &two, &oper);
              Log()<<"新线程完成计算任务: "<< one << oper << two << "=" << t.run() << "\n";
          }
      }
      //调用start, 线程池开始工作
      void start()
      {
          assert(!isStart_);
          for(int i = 0; i < threadNum_; ++i)
          {
              pthread_t temp;
              pthread_create(&temp, nullptr, threadRoutine, this);
          }
          isStart_ = true;
      }
      void push(const T& in)
      {
          lockQueue();
          taskQueue_.push(in);
          choiceThreadForHandler();
          unlockQueue();
      }
  private:
      void lockQueue() { pthread_mutex_lock(&mutex_); }
      void unlockQueue() { pthread_mutex_unlock(&mutex_); }
      bool haveTask() { return !taskQueue_.empty(); }  //有无任务
      void waitForTask() { pthread_cond_wait(&cond_, &mutex_); }
      void choiceThreadForHandler() { pthread_cond_signal(&cond_); } //选择一个线程去处理
      T pop()
      {
          T temp = taskQueue_.front();
          taskQueue_.pop();
          return temp;
      }
  private:
      bool isStart_;
      int threadNum_;
      queue<T> taskQueue_;  //任务队列
      pthread_mutex_t mutex_;  //互斥锁
      pthread_cond_t cond_;
  };
  //测试线程池
  #include "ThreadPool.hpp"
  #include "Task.hpp"
  #include "Log.hpp"
  #include
  #include
  #include
  int main()
  {
      prctl(PR_SET_NAME, "master");
      const string operators = "+-*/";
      ThreadPool<Task>* tp = new ThreadPool<Task>();
      tp->start();
      srand((unsigned long)time(nullptr) ^ getpid() ^ pthread_self());
      //派发任务
      while(true)
      {
          int one = rand() % 50;
          int two = rand() % 10;
          char oper = operators[rand() % operators.size()];
          Log() << "主线程派发计算任务" << one << oper << two << "=?" << "\n";
          Task t(one, two, oper);
          tp->push(t);
          sleep(1);
      }
      return 0;
  }
 

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!