Linux 线程池类

本文详细介绍了线程池的实现,包括构造函数中创建线程、向请求队列添加任务、线程处理函数以及任务执行过程。线程池通过互斥锁和信号量确保线程安全,使用数据库连接池管理数据库连接,有效提高了系统资源利用率和效率。
摘要由CSDN通过智能技术生成
  • 线程池类定义

     1template<typename T>
     2class threadpool{
     3    public:
     4        //thread_number是线程池中线程的数量
     5        //max_requests是请求队列中最多允许的、等待处理的请求的数量
     6        //connPool是数据库连接池指针
     7        threadpool(connection_pool *connPool, int thread_number = 8, int max_request = 10000);
     8        ~threadpool();
     9
    10        //像请求队列中插入任务请求
    11        bool append(T* request);
    12
    13    private:
    14        //工作线程运行的函数
    15        //它不断从工作队列中取出任务并执行之
    16        static void *worker(void *arg);
    17
    18        void run();
    19
    20    private:
    21        //线程池中的线程数
    22        int m_thread_number;
    23
    24        //请求队列中允许的最大请求数
    25        int m_max_requests;
    26
    27        //描述线程池的数组,其大小为m_thread_number
    28        pthread_t *m_threads;
    29
    30        //请求队列
    31        std::list<T *>m_workqueue;    
    32
    33        //保护请求队列的互斥锁    
    34        locker m_queuelocker;
    35
    36        //是否有任务需要处理
    37        sem m_queuestat;
    38
    39        //是否结束线程
    40        bool m_stop;
    41
    42        //数据库连接池
    43        connection_pool *m_connPool;  
    44};
    
  • 线程池创建与回收

    构造函数中创建线程池,pthread_create函数中将类的对象作为参数传递给静态函数(worker),在静态函数中引用这个对象,并调用其动态方法(run)。

     1template<typename T>
     2threadpool<T>::threadpool( connection_pool *connPool, int thread_number, int max_requests) :
      m_thread_number(thread_number), m_max_requests(max_requests), m_stop(false), m_threads(NULL),m_connPool(connPool)
      {
     3
     4    if(thread_number<=0||max_requests<=0)
     5        throw std::exception();
     6
     7    //线程id初始化
     8    m_threads=new pthread_t[m_thread_number];
     9    if(!m_threads)
    10        throw std::exception();
    11    for(int i=0;i<thread_number;++i)
    12    {
    13        //循环创建线程,并将工作线程按要求进行运行
    14        if(pthread_create(m_threads+i,NULL,worker,this)!=0){
    15            delete [] m_threads;
    16            throw std::exception();
    17        }
    18
    19        //将线程进行分离后,不用单独对工作线程进行回收
    20        if(pthread_detach(m_threads[i])){
    21            delete[] m_threads;
    22            throw std::exception();
    23        }
    24    }
    25}
    

    具体的,类对象传递时用this指针,传递给静态函数后,将其转换为线程池类,并调用私有成员函数run。

  • 向请求队列中添加任务

    通过list容器创建请求队列,向队列中添加时,通过互斥锁保证线程安全,添加完成后通过信号量提醒有任务要处理,最后注意线程同步。

     1template<typename T>
     2bool threadpool<T>::append(T* request)
     3{
     4    m_queuelocker.lock();
     5
     6    //根据硬件,预先设置请求队列的最大值
     7    if(m_workqueue.size()>m_max_requests)
     8    {
     9        m_queuelocker.unlock();
    10        return false;
    11    }
    12
    13    //添加任务
    14    m_workqueue.push_back(request);
    15    m_queuelocker.unlock();
    16
    17    //信号量提醒有任务要处理
    18    m_queuestat.post();
    19    return true;
    20}
    
  • 线程处理函数

    内部访问私有成员函数run,完成线程处理要求。

    1template<typename T>
    2void* threadpool<T>::worker(void* arg){
    3
    4    //将参数强转为线程池类,调用成员方法
    5    threadpool* pool=(threadpool*)arg;
    6    pool->run();
    7    return pool;
    8}
    
  • run执行任务

    主要实现,工作线程从请求队列中取出某个任务进行处理,注意线程同步。

    template<typename T>
     2void threadpool<T>::run()
     3{
     4    while(!m_stop)
     5    {    
     6        //信号量等待
     7        m_queuestat.wait();
     8
     9        //被唤醒后先加互斥锁
    10        m_queuelocker.lock();
    11        if(m_workqueue.empty())
    12        {
    13            m_queuelocker.unlock();
    14            continue;
    15        }
    16
    17        //从请求队列中取出第一个任务
    18        //将任务从请求队列删除
    19        T* request=m_workqueue.front();
    20        m_workqueue.pop_front();
    21        m_queuelocker.unlock();
    22        if(!request)
    23            continue;
    24
    25        //从连接池中取出一个数据库连接
    26        request->mysql = m_connPool->GetConnection();
    27
    28        //process(模板类中的方法,这里是http类)进行处理
    29        request->process();
    30
    31        //将数据库连接放回连接池
    32        m_connPool->ReleaseConnection(request->mysql);
    33    }
    34}
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值