欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程池

程序员文章站 2022-07-12 19:50:48
...

线程池,首先要明白,线程池是用来管理线程类的,线程类的实现可以参考我前面说过的方法,连接:

 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;
    }
}