自己动手写http服务器——线程池(一)

创建一个线程池,每有一个连接对象就将它添加到工作队列中,线程池中的线程通过竞争来取得任务并执行它(它是通过信号量实现的)。

//filename threadpool.h
#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <list>
#include <cstdio>
#include <exception>
#include <pthread.h>

#include <locker.h>

template <typename T>
class threadpool{
private:
    int m_thread_number;     //线程池中的线程数
    int m_max_requests;       //请求队列中允许的最大请求数
    pthread_t *m_threads;     //描述线程池的数组
    std::list<T*> m_workqueue; //请求队列
    locker m_queuelocker;
    sem m_queuestat;              //信号量,是否有请求需要处理
    bool m_stop;                       //是否结束线程
public:
    threadpool(int thread_number=8;int max_requests=10000);
    ~threadpool();
    bool append(T* request);    //往请求队列中添加请求
    static void * worker(void *arg);  //工作线程运行的函数
    void run();
};

template<typename T>
threadpool<T>::threadpool(int thread_number,int max_requests):m_thread_number(thread_number),
                                                                                                       m_max_requests(max_requests),m_stop(false),m_threads(NULL){
    if((thread_number<=0)||(max_requests<=0)){
        throw std::exception();
    }

    m_threads=new pthread_t[m_thread_number];  
    if(!m_threads){
    throw std::exception();
    }

    //创建线程,并将他们都设为分离线程,这样线程结束时就能自动释放资源
    for(int i=0;i<m_thread_number;++i){
        printf("create the %dth thread
",i);
        if(pthread_create(m_threads+i,NULL,worker,this)!=0){
            delete [] m_threads;
            throw std::exception();
        }

        if(pthread_detach(m_threads[i])){
            delete [] m_threads;
            throw std::exception();
        }
    }
}

template<typename T>
threadpool<T>::~threadpool(){
    delete [] m_threads;
    m_stop=true;
}

template<typename T>
threadpool<T>::append(T *request){
    m_queuelocker.lock();
    if(m_workqueue.size() > m_max_requests){
        m_queuelocker.unlock();
        return false;
    }
    
    m_workqueue.push_back(request);
    m_queuelocker.unlock();
    m_queuestat.post();
    return true;
}

template<typename T>
void * threadpool<T>::worker(void *arg){
    threadpool * pool=(threadpoll *)arg;
    pool->run();
    return pool;
}

template<typename T>
void threadpool<T>::run(){
    while(!m_stop){
        m_queuestat.wait();
        m_queuelocker.lock();
        if(m_workqueue.empty()){
            m_queuestat.unlock();
            continue;
        }

        T* request =m_workqueue.front();
        m_workqueue.pop_front();
        m_queuelocker.unlock();
        if(!request){
        continue;
        }
        request->process();
    }
}
#endif
原文地址:https://www.cnblogs.com/CodingUniversal/p/7522727.html