muduo源码学习(8)-ThreadPool
来源:互联网 发布:淘宝联盟怎么合并购买 编辑:程序博客网 时间:2024/06/05 17:18
多线程可以提高效率,当由于资源限制,不可能创建大量的线程,与CPU核数有关,而且,当处理任务是,临时的创建线程,销毁线程比较费时,比较理想的做法是实现创建一定数量的线程,然后线程不断的接受任务,在线程中处理任务,这就是线程池,java类库中有线程池,c++需要自己封装,muduo中就通过了线程池类。线程池本质上还是生产者消费者模型。线程池类中有一个任务队列,工作线程不断的消费任务,生产者添加任务。
在base/ThreadPool.h中
class ThreadPool : boost::noncopyable{ public: //任务 typedef boost::function<void ()> Task; explicit ThreadPool(const string& name = string()); ~ThreadPool(); void start(int numThreads); void stop(); void run(const Task& f); private: void runInThread(); Task take(); MutexLock mutex_; Condition cond_; string name_; //存放Thread * boost::ptr_vector<muduo::Thread> threads_; //任务队列 std::deque<Task> queue_; //是否在运行 bool running_;};主要成员就是一个队列,条件变量,锁,threads_存放Thread *指针
base/ThreadPool.cc
ThreadPool::ThreadPool(const string& name) : mutex_(), cond_(mutex_), name_(name), running_(false){}ThreadPool::~ThreadPool(){ if (running_) { stop(); }}//启动线程池void ThreadPool::start(int numThreads){ assert(threads_.empty()); running_ = true; threads_.reserve(numThreads); //´´½¨Ïß³Ì for (int i = 0; i < numThreads; ++i) { char id[32]; snprintf(id, sizeof id, "%d", i);//创建线程 threads_.push_back(new muduo::Thread( boost::bind(&ThreadPool::runInThread, this), name_+id));//启动线程threads_[i].start(); }}//停止void ThreadPool::stop(){ { MutexLockGuard lock(mutex_); running_ = false; // cond_.notifyAll(); }/调用join() for_each(threads_.begin(), threads_.end(), boost::bind(&muduo::Thread::join, _1));}//加入任务void ThreadPool::run(const Task& task){// if (threads_.empty()) { task(); } else { MutexLockGuard lock(mutex_); queue_.push_back(task); cond_.notify(); }}//获取任务ThreadPool::Task ThreadPool::take(){ MutexLockGuard lock(mutex_); // always use a while-loop, due to spurious wakeup while (queue_.empty() && running_) { cond_.wait(); } Task task; if(!queue_.empty()) { task = queue_.front(); queue_.pop_front(); } return task;}//工作线程中调用void ThreadPool::runInThread(){ try { while (running_) { //获取任务 Task task(take()); if (task) { //调用任务 task(); } } } catch (const Exception& ex) { fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); fprintf(stderr, "reason: %s\n", ex.what()); fprintf(stderr, "stack trace: %s\n", ex.stackTrace()); abort(); } catch (const std::exception& ex) { fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); fprintf(stderr, "reason: %s\n", ex.what()); abort(); } catch (...) { fprintf(stderr, "unknown exception caught in ThreadPool %s\n", name_.c_str()); throw; // rethrow }}
维护了一个线程安全的任务队列,启动线程池后,工作线程不断的调用take()获取任务,如果没有任务,可能会等待,之后调用任务函数。在析构函数中,调用stop(),唤醒所有可能阻塞在take()的线程,此时runing为false,循环结束,线程结束。
阅读全文
0 0
- muduo源码学习(8)-ThreadPool
- muduo源码分析:线程池类ThreadPool
- muduo : ThreadPool
- muduo源码学习(1)
- muduo源码学习(7)-队列
- muduo源码学习(9)-单例类
- muduo源码学习(10)-ThreadLocal
- muduo源码学习(18)-EventLoopThread
- muduo库的ThreadPool剖析
- muduo网络库学习之BlockinngQueue<T>类、ThreadPool 类、Singleton类封装中的知识点
- muduo 6 网络库学习之BlockinngQueue<T>类、ThreadPool 类、Singleton类封装中的知识点
- muduo源码学习(2)-Timestamp
- muduo源码学习(3)-原子操作
- muduo源码学习(4)-自定义异常
- muduo源码学习(5)-线程封装
- muduo源码学习(6)-锁,条件变量
- muduo源码学习(14)-网络库类库概述
- muduo源码学习(16)-EventLoop简介
- 在VS和Linux下逆序打印单链表(递归和非递归)
- 【新手指南】如何使用手机通过wifi直接连接打印机并打印
- SVN 版本管理系统的安装
- cocos2d-x 源码分析 之 CCTableView源码分析(附使用方法讨论)
- 《程序员的修炼之道》笔记——2、软件的熵
- muduo源码学习(8)-ThreadPool
- Bad Cowtractors(Kruskal)
- 最大值减去最小值小于等于num的子数组数量
- 浮点数陷阱
- filter详解
- Rhino| Rhino详细介绍与实战
- maven 中的快照版本的讲解(SNAPSHOT)
- Java实现汉诺塔 -- JAVA 算法学习
- elasticsearch之Document APIs【Reindex API】