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

Linux:线程池 / 及如何创建一个线程池

发布时间:2022-12-07 11:24:11 所属栏目:Linux 来源:
导读:  线程池:通俗一点来说,就是一个有着很多线程的池子,线程数量由线程池的最大线程容量控制。当有需要处理的任务到来时,从线程池中取出一个线程去处理这个任务。

  应用场景:有大量的数据处理请求,需要执
  线程池:通俗一点来说,就是一个有着很多线程的池子,线程数量由线程池的最大线程容量控制。当有需要处理的任务到来时,从线程池中取出一个线程去处理这个任务。
 
  应用场景:有大量的数据处理请求,需要执行流并行或并发处理
 
  若是每次有一个数据请求的到来需要去创建线程去处理,处理完销毁则会产生风险以及一些不必要的消耗:
 
  线程如若不限制线程创建的数量,在峰值压力下,线程创建过多,资源耗尽,有程序崩溃的风险。创建一个线程的时间:线程创建+任务处理+线程销毁,如果任务处理的时间占比不高,则说明大量的资源都用于了线程的创建和销毁上线程池linux,因此线程池用创建好的线程循环处理任务,避免了大量的线程创建和线程销毁的时间成本。 自主创建一个线程池
 
  线程池组成:大量线程(每个线程循环的进行任务处理)+ 任务缓冲处理
 
  在这里插入图片描述
 
  线程池中的线程每次从任务队列的队首获取一个任务进行处理,线程间以此循环往复。
 
  几个问题:
 
  线程的入口函数都是在线程创建初传入线程的,会导致线程池中的线程进行任务处理的方式单一线程的入口函数都一样,处理流程也就一样,只有单一的处理方式,灵活性太差
 
  解决办法:
 
  若任务队列中的任务,不仅仅是单纯的传入数据,并且包含了任务处理方式(入口函数),这时线程池中的线程只需要根据任务的数据和处理函数对数据进行处理,而不用关心是什么数据该如何处理。
 
  代码:
 
  #include
  #include
  #include
  #include
  #include
  using namespace std;
  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 Max_pthread 4
  class pthreadpool{
  
  public:
   pthreadpool(int max=Max_pthread)
   :_max(max)
   {
   pthread_mutex_init(&mutex,NULL);
   pthread_cond_init(&cond,NULL);
   for(int i=0;i<_max;i++)
   {
   pthread_t pthread;
   int ret=pthread_create(&pthread,NULL,thr_start,this);
   if(ret!=0)
   {
   printf("create error\n");
   exit(-1);
   }
   }
   }
   ~pthreadpool()
   {
   _max=0;
   pthread_mutex_destroy(&mutex);
   pthread_cond_destroy(&cond);
   }
   bool taskpush(Task& task)
   {
   pthread_mutex_lock(&mutex);
   queue.push(task);
   pthread_mutex_unlock(&mutex);
   pthread_cond_broadcast(&cond);
   return true;
   }
   static void* thr_start(void* arg)
   {
   pthread_cond_broadcast(&p->cond);//唤醒所有线程,让他们随机去获取这个任务
   pthreadpool* p=(pthreadpool*)arg;
   while(1)
   {
   //对从任务队列中获取任务操作进行上锁,保证线程安全
   pthread_mutex_lock(&p->mutex);
   while(p->queue.empty())    //任务队列如果为空,进行线程等待
   {
   pthread_cond_wait(&p->cond,&p->mutex);
   }
   Task task;
   task=p->queue.front();
   p->queue.pop();
   pthread_mutex_unlock(&p->mutex);//获取完任务后进行解锁
   task.Run();
   }
  
   }
  private:
   pthread_mutex_t mutex;
   pthread_cond_t cond;
   std::queue<Task> queue;
   int _max;
  };
  定义一个任务类和线程池类
 
  #include"test.hpp"
  #include
  void func1(int data)
  {
   int sec=(data%3)+1;
   printf("tid:%p----data:%d----sleep:%d\n",pthread_self(),data,sec);
   sleep(sec);
  }
  void func2(int data)
  {
   printf("tid:%p--data:%d--func2\n",pthread_self(),data);
   sleep(1);
  }
  int main()
  {
   pthreadpool pool;
   for(int i=0;i<10;i++)
   {
   Task task;
   if(i%2==0)
   task.settask(i,func1);
   else
   task.settask(i,func2);
   pool.taskpush(task);
   }
   sleep(1000);
   return 0;
  }
  定义了两个任务处理函数,和10个任务进行处理
 

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

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