如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不可忽视,通过线程池也避免这种不必要的开销。线程池的基本思想是预先创建一些线程,这些线程用于处理以后需要用到线程来处理的事情,从而做到不需要每次都创建线程。
需要注意的怎么管理线程任务,一般用链表结构来保存需要处理的任务,线程循环从链表中取出任务来处理,如果链表中已经不存在任务,线程就一直等待,知道有任务加入到链表中。如果理解了以上思路,实现还是比较简单的。这里直接贴上代码。
#ifndef THREADPOOL_THREAD_POOL_H_
#define THREADPOOL_THREAD_POOL_H_
#include "job.h"
#include "thread.h"
class ThreadPool
{
public:
friend class Thread;
ThreadPool(size_t thread_num):m_thread_num_(thread_num)
{
pthread_mutex_init(&m_thread_mutex_, NULL);
pthread_cond_init(&m_thread_cond_, NULL);
}
void run();
static void* routine(void*);
pthread_mutex_t& getMutex()
{
return m_thread_mutex_;
}
pthread_cond_t& getCond()
{
return m_thread_cond_;
}
std::vector<boost::shared_ptr<Thread> > getThreadVec()
{
return m_thread_vec_;
}
bool hasElement()
{
bool ret;
pthread_mutex_lock(&m_thread_mutex_);
if(m_proc_vec_.empty())
{
ret = false;
}
else
{
ret = true;
}
pthread_mutex_unlock(&m_thread_mutex_);
return ret;
}
void addJob(Fun fun, void* arg)
{
pthread_mutex_lock(&m_thread_mutex_);
m_proc_vec_.push_back(new Process(fun, arg));
pthread_mutex_unlock(&m_thread_mutex_);
pthread_cond_signal(&m_thread_cond_);
}
Process* getFirtJob()
{
pthread_mutex_lock(&m_thread_mutex_);
if(m_proc_vec_.empty())
{
pthread_mutex_unlock(&m_thread_mutex_);
return NULL;
}
Process* proc;
proc = m_proc_vec_.front();
m_proc_vec_.pop_front();
pthread_mutex_unlock(&m_thread_mutex_);
return proc;
}
private:
size_t m_thread_num_;
pthread_mutex_t m_thread_mutex_;
pthread_cond_t m_thread_cond_;
std::vector<boost::shared_ptr<Thread> > m_thread_vec_;
std::list<Process*> m_proc_vec_;
};
#endif
#ifndef THREADPOOL_THREAD_H_
#define THREADPOOL_THREAD_H_
#include "pch.h"
class ThreadPool;
class Thread
{
public:
Thread(ThreadPool* pool)
{
m_thread_pool_ = pool;
pthread_create(&m_pthread_t_, NULL, Thread::routine,this);
}
void run();
void join();
static void* routine(void* arg);
ThreadPool* getThreadPool()
{
return m_thread_pool_;
}
private:
pthread_t m_pthread_t_;
//std::string m_thread_name_;
ThreadPool* m_thread_pool_;
};
#endif
thread.cpp
void Thread::run()
{
pthread_join(m_pthread_t_, NULL);
}
void* Thread::routine(void* arg)
{
Thread* obj = (Thread*)arg;
pthread_cond_t& cond = obj->getThreadPool()->getCond();
pthread_mutex_t& mutex = obj->getThreadPool()->getMutex();
while (1)
{
//std::cout<<"----begind----"<<std::endl;
//pthread_mutex_lock(&mutex);
while(!obj->getThreadPool()->hasElement())
{
pthread_cond_wait(&cond, &mutex);
}
//pthread_mutex_unlock(&mutex);
Process* proc = obj->getThreadPool()->getFirtJob();
if (proc)
{
proc->run();
}
}
return NULL;
}