0


【linux多线程(四)】——线程池的详细解析(含代码)


【linux线程(壹)】——初识线程(区分线程和进程,线程创建的基本操作)
【线程(二)】——互斥量的详细解析
【线程(三)】———条件变量的详细解析

什么是线程池?

线程池是一种线程使用模式,它是将一定数量线程和缓冲队列预存在一个池子中,池子中的线程轮流的往任务队列中拿去任务并完成任务,而任务队列往外开发一个接口,使其他线程能够往任务队列中推送任务。

线程池的优点:

线程池能够减少线程的创建和销毁所消耗的时间和系统资源的开销,如果不使用线程池,将可能造成系统创建大量的同类线程而导致消耗完内存或“过度切换”的问题。

线程池的应用场景

1,需要大量线程来完成任务,且完成任务的时间较短,WEB服务器完成网页请求这样的任务使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,但对于长时间的任务,比如一个Telnet连接请求,线程池的优点不明显,因为Telnet会话时间比线程的创建时间太多了。

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

3.接受突发的大量请求时,但不至于使服务器创建大量的线程,在没有线程池情况下,将产生大量的线程,短时间内会产生大量的线程可能使内存达到极限,出现错误。

线程池的实现

线程池的成员变量:

  • 任务队列,quueu<T> q;
  • 线程个数,int num;
  • 互斥量,pthread_mutex_t lock;
  • 条件变量,pthread_cond_t cond;

创建线程池,需要创建一个任务队列和一定数量的线程。由于每次只能有一个线程进入队列中放任务和拿任务,所以此时需要定义一个互斥量进行维护,如果任务队列中的没有任务,此时线程就不能进入任务队列中,所以就创建一个条件变量。

线程池的代码(C++)

** makefile文件**

threadpool:threadpool.cc    
  g++ $^ -o [email protected] -lpthread                                                                                                                                     
    
clean:    
  rm -f threadpool

Task.hpp文件

#pragma  once    
#include<iostream>    
#include<stdio.h>    
using namespace std;    
class Task    
{    
  private:    
    int x;int y;    
    char op;                                                                                                                                                 
  public:       
    Task(int _x,int _y,char _op)    
      :x(_x)                        
      ,y(_y)    
      ,op(_op){ }    
    Task()           
    {};       
    void Run()    
    {             
      int ret=0;    
      switch(op){    
        case '+':    
          ret=x+y;    
          break;                     
        case '-':                    
          ret=x-y;                   
          break;                     
        case '*':            
          ret=x*y;
          break;
          case '/':
          ret=x/y;
          break;
          case '%':
          ret=x%y;
          break;
      }
      printf("%d %c %d = %d\n",x,op,y,ret);
    } 
};                                    

** threadpool.hpp文件 **

#pragma once    
#include<iostream>                                                                                                                                           
#include<queue>    
#include<pthread.h>    
#include<unistd.h>    
using namespace std;    
    
    
#define NUM 4    
template<class T>    
class ThreadPool    
{    
  private:    
    queue<T> q;//任务队列    
    int thread_num;//线程池的线程数量    
    pthread_mutex_t lock;//互斥锁    
    pthread_cond_t cond;//条件变量    
  public:    
    ThreadPool(int num=NUM)//初始化变量
      :thread_num(num){    
        pthread_mutex_init(&lock,NULL);    
        pthread_cond_init(&cond,NULL);    
    }    
    
    bool Empty()    
    {    
      return q.size()==0?true:false;     
    }    
    
   static  void* Routine(void* arg)//线程执行流    
    {    
      pthread_detach(pthread_self());//线程分离    
      ThreadPool* self=(ThreadPool*)arg;
      while(1)
      {
        self->LockQueue();
        while(self->Empty())//任务队列是否为空
        {
          self->Wait();
        }
        T data;
        self->Pop(data);//取出任务
        self->UnlockQueue();

        cout<<pthread_self()<<"# ";                                                                                                                          
        //处理任务
        data.Run();//处理任务
        sleep(1);
      }
    }

    void Wait()//线程等待
    {
      pthread_cond_wait(&cond,&lock);
    }

    void LockQueue()//锁住队列
    {
      pthread_mutex_lock(&lock);
    }

    void UnlockQueue()//解锁队列
    {
      pthread_mutex_unlock(&lock);
    }

    void ThreadPoolInit()
    {
      pthread_t tid;
      for(int i=0;i<thread_num;i++)//创建线程池中的线程
      {
        pthread_create(&tid,NULL,Routine,(void*)this);
      }
    }

    void Push(const T& in)//将任务推进任务队列中
    {
      LockQueue();
      q.push(in);
      UnlockQueue();
      SignalThread();
    }

    void SignalThread()//唤醒cond变量下的线程
    {
      pthread_cond_signal(&cond);
    }

    void Pop( T& out)//取出任务队列中的任务
    {
      out=q.front();
      q.pop();
    }

    ~ThreadPool()
    {
      pthread_mutex_destroy(&lock);
      pthread_cond_destroy(&cond);
    }
};                      

threadpool.cc 文件

#include"threadpool.hpp"    
#include"Task.hpp"    
#include<time.h>    
#include<stdlib.h>    
int main()    
{    
  ThreadPool<Task> * q=new ThreadPool<Task>();//创建线程池    
  q->ThreadPoolInit();    
  srand((long int)time(NULL));    
  while(1)  //主线程往任务队列中放任务  
  {    
    char arr[]="+-*/%";    
    int x=rand()%100+1;    
    int y=rand()%100+1;    
    char op=arr[rand()%5];    
    Task t(x,y,op);//创建任务    
    q->Push(t);//将任务推送给队列中    
  }                                                                                                                                                          
  return 0;    
}  

运行结果:

标签: linux 运维 服务器

本文转载自: https://blog.csdn.net/sjp11/article/details/122914857
版权归原作者 努力学习的少年 所有, 如有侵权,请联系我们删除。

“【linux多线程(四)】&mdash;&mdash;线程池的详细解析(含代码)”的评论:

还没有评论