线程池——Linux系统编程

线程池

  1. 线程池=线程安全队列+一大堆的线程(消费线程)
  2. 线程池中的线程,都是同一种角色的线程,每一个线程都执行同样的入口函数
  3. 线程安全队列中的元素,保存待处理的数据和处理数据的方式

如何让相同入口函数的线程,处理不同的请求

  1. switch case:处理大量不同的需求的时候,比较麻烦
  2. 向线程池抛入数据的时候,将处理该数据的函数一起抛入(函数地址),线程池当中的线程只需要调入传入的处理函数处理传入的数据即可
#include <iostream>                                                                   
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <queue>

//线程池=线程安全队列+一大堆的线程
//线程安全队列的元素:数据+处理数据的函数地址
//
//
#define THREADCOUNT 4

//函数指针
typedef void* (*Handler_t)(int);

//定义队列元素类型
class ThreadTask
{
public:
    ThreadTask(int data,Handler_t handler)
    {
        data_=data;
        handler_=handler;
    }

    ~ThreadTask()
    {

    }
    //使用函数,处理数据
    void Run()
    {
        handler_(data_);
    }
private:
    int data_;
    Handler_t handler_;
};

//线程池
class ThreadPool
{
public:
     ThreadPool()
     {
        //队列的大小
        capacity_=10;
        //线程池中线程的大小
        thread_capacity_=THREADCOUNT;
        
        //互斥和同步
        pthread_mutex_init(&lock_,NULL);
        pthread_cond_init(&cond_,NULL);

        //创建线程     
                bool is_create=ThreadCreate();
        if(!is_create)
        {
            printf("Threadpool Create Thread Failed\n");
            exit(1);
        }

        IsExit=false;
        cur_thread_count_=THREADCOUNT;
     }

     ~ThreadPool()
     {

     }

     bool Push(ThreadTask* tt)
     {
         pthread_mutex_lock(&lock_);
         if(IsExit)
         {
             pthread_mutex_unlock(&lock_);
             return false;
         }
         que_.push(tt);
         pthread_mutex_unlock(&lock_);

         //插入数据之后,通知线程池当中的线程(消费)        
            pthread_cond_signal(&cond_);

         return true;
     }

     bool Pop(ThreadTask** tt)
     {
         *tt=que_.front();
         que_.pop();

         return true;
     }

     void ThreadJoin()
     {
         for(int i=0;i<THREADCOUNT;i++)
         {
             pthread_join(tid_[i],NULL);
         }
     }
     
     void ThreadExit()
     {
         for(int i=0;i<THREADCOUNT;i++)
         {
             pthread_cancel(tid_[i]);
         }
     }

     void ThreadPoolClear() 
          {
         //标志位
         pthread_mutex_lock(&lock_);
         IsExit=true;
         pthread_mutex_unlock(&lock_);
         if(cur_thread_count_>0)
         {
            pthread_cond_broadcast(&cond_);
         }
     }
private:
     //加static修饰,函数传递的参数没有this指针
     static void* THreadstart(void* arg)
     {
         ThreadPool* tp=(ThreadPool*)arg;
         while(1)
         {
             //从队列中获取数据进行消费
             pthread_mutex_lock(&tp->lock_);
             ThreadTask* tt;
             while(tp->que_.empty())
             {  
                 if(tp->IsExit)
                 {
                     tp->cur_thread_count_--;
                     pthread_mutex_unlock(&tp->lock_);
                     //退出
                     pthread_exit(NULL);
                 }                               
                                  //调用条件变量等待接口
                 pthread_cond_wait(&tp->cond_,&tp->lock_);
             }
             tp->Pop(&tt);
             pthread_mutex_unlock(&tp->lock_);

             //调用队列当中元素提供的函数,去处理数据
             tt->Run();
             delete tt;
         }
     }
     bool ThreadCreate()
     {
         for(int i=0;i<THREADCOUNT;i++)
         {
             int ret=pthread_create(&tid_[i],NULL,THreadstart,(void*)this);
             if(ret!=0)
             {
                 perror("pthread_create");
                 return false;
             }
         }
         return true;
     }
private:
    std::queue<ThreadTask*> que_;
    size_t capacity_;
    //互斥
    pthread_mutex_t lock_;

    //同步
    pthread_cond_t cond_;

    //线程当中初始化的时候线程数量
    size_t thread_capacity_;

    //线程池中具体还有多少线程
    size_t cur_thread_count_;

    //保存线程池当中的线程的标识符
    pthread_t tid_[THREADCOUNT];

    //标志是否可以退出
    bool IsExit;
};

void* DealData(int data)
{
    printf("消费的数据是 %d\n",data);
    return NULL;
}


int main()  
{
    ThreadPool* tp=new ThreadPool();
    for(int i=1;i<=50;i++)
    {
        ThreadTask* tt=new ThreadTask(i,DealData);
        tp->Push(tt);
    }
    
    sleep(15);
    //等待线程池中线程退出
    tp->ThreadPoolClear();
    tp->ThreadJoin();
    delete tp;
    return 0;
}                  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值