线程池
线程池,首先要明白,线程池是用来管理线程类的,线程类的实现可以参考我前面说过的方法,连接:
http://konin.iteye.com/blog/2333332
既然是管理线程类,就必须要有一个容器(池子)来装这些线程类,同时间,要知道有那些线程类处于运行工作的状态,所以还要有一个容器装运行状态的线程
什么情况下需要用到线程池?
场景1、一个业务,可以通过某种规则,用多个线程来处理,而这些线程可以分别独立处理这个业务而不互相干扰,比如1000万条记录,每条记录的关键字段是数字,数字分别以0到9结尾,那么就可以用10个线程来处理,用一个线程池来管理这10个线程。
实现步骤 声明:
class ThreadPool {
public:
/**
* 线程列表类型
*/
typedef set<Thread*> ThreadSet;
/**
* 构造函数
*/
ThreadPool();
/**
* 析构函数
*/
virtual ~ThreadPool();
/**
* 添加线程对象
* @param thread 线程对象, 由ThreadPool负责释放
*/
void addThread(Thread* thread);
/**
* 获取线程集合
*/
const ThreadSet& getThreadSet() const;
/**
* 运行线程池里的线程
* @return 实际运行线程数, 0表示没有运行任何线程
*/
int start();
/**
* 等待已经运行的线程完成运行
* @return 结束的线程数
*/
int join();
/**
* 清空线程池
*/
void clear();
protected:
/**
* 添加线程
*/
void doAddThread(Thread* thread);
/**
* 运行线程实现
*/
int doStart(int n);
ThreadSet _threads;
ThreadSet _runningThreads;
Mutex _mutex;
};
实现
ThreadPool::ThreadPool() {}
ThreadPool::~ThreadPool() {
join();
clear();
}
void ThreadPool::addThread(Thread* thread) {
LockGuard<Mutex> guard(_mutex);
(void)guard;
doAddThread(thread);
}
const ThreadPool::ThreadSet& ThreadPool::getThreadSet() const {
return _threads;
}
void ThreadPool::doAddThread(Thread* thread) {
_threads.insert(thread);
}
int ThreadPool::start() {
LockGuard<Mutex> guard(_mutex);
(void)guard;
return doStart(static_cast<int>(_threads.size()));
}
int ThreadPool::doStart(int n) {
int i = 0;
for (ThreadSet::const_iterator iter = _threads.begin(); n >= 0 && iter != _threads.end(); ++iter) {
(*iter)->start();
_runningThreads.insert(*iter);
++i;
--n;
}
return i;
}
int ThreadPool::join() {
LockGuard<Mutex> guard(_mutex);
(void)guard;
int n = static_cast<int>(_runningThreads.size());
while (!_runningThreads.empty()) {
ThreadSet::iterator iter = _runningThreads.begin();
(*iter)->join();
_runningThreads.erase(iter);
}
return n;
}
void ThreadPool::clear() {
for (ThreadSet::const_iterator iter = _threads.begin(); iter != _threads.end(); ++iter) {
delete *iter;
}
}