线程池
线程池类封装
对threadpool类采用模版类,方便处理各种各样不同类型的请求
线程池必要的属性:
1.线程的数量
2.描述线程池数组的指针
3.请求队列
4.请求队列的最大长度
5.互斥锁(用来对请求队列进行互斥操作)
6.信号量(是否有信号需要进行处理)
7.线程的结束标志
成员函数:
1.构造
2.析构
3.往请求队列里添加新请求
4.工作线程运行的函数
template <typename T>
class threadpool{
public:
threadpool(int pthread_number = 8, int max_requests = 10000);
~threadpool();
bool append(T* request);
private:
//工作线程运行的函数,它不断从工作队列中取出任务并执行之
static void* worker(void* arg);
void run();
private:
int m_pthread_number; //线程的数量
pthread_t * m_threads; //描述线程池的数组
int m_max_requests; //请求队列的最大长度
std::list<T*> m_workqueue; //请求队列
locker m_queuelocker; //保护请求队列的互斥锁
sem m_queuestat; //是否有信号需要处理
bool m_stop; //是否结束线程
};
线程池类的构造
将有参构造传进来的线程的数量和请求队列的最大长度分别进行初始化,m_stop初始化为false,请求队列的指针指向NULL方便后续操作。
1.初始化一个长度为m_pthread_number的数组(即线程池本池)
2.创建m_pthread_number个线程并设置线程分离
template<typename T>
threadpool<T> :: threadpool(int thread_number, int max_requests)
:m_pthread_number(thread_number), m_max_requests(max_requests),
m_stop(false), m_threads(NULL) {
if(m_pthread_number <= 0 || m_max_requests <= 0) {
throw std::exception();
}
m_threads = new pthread_t[m_pthread_number];
if(!m_threads) {
throw std::exception();
}
//创建m_thread_number个线程并设置线程分离
for(int i = 0; i < m_pthread_number; i++) {
printf("create the %dth thread",i+1);
if(pthread_create(m_threads + i, NULL, worker, this) != 0){
delete[] m_threads;
throw std::exception();
}
//设置线程分离
if(pthread_detach(m_threads[i]) != 0) {
delete[] m_threads;
throw std::exception();
}
}
}
线程池类的析构
template<typename T>
threadpool<T> :: ~threadpool(){
delete[] m_threads;
m_stop = true;
}
向请求队列中添加新请求
template<typename T>
bool 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 = (threadpool*)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_queuelocker.unlock();
continue;
}
T * request = m_workqueue.front();
m_workqueue.pop_front();
m_queuelocker.unlock();
if(!request){
continue;
}
request->process(); //最后由当前线程去处理这个请求,处理函数process()
}
}