muduo源码分析--线程池的实现
来源:互联网 发布:淘宝友情链接 编辑:程序博客网 时间:2024/05/16 05:52
muduo线程池主要有3个类的实现:EventLoop,EventLoopThreadPool,EventLoopThread,和Thread.
1.Thread为对一个线程的封装:
class Thread : boost::noncopyable{ public: typedef boost::function<void ()> ThreadFunc; //创建线程时,传递的函数 explicit Thread(const ThreadFunc&, const string& name = string());#ifdef __GXX_EXPERIMENTAL_CXX0X__ explicit Thread(ThreadFunc&&, const string& name = string());#endif ~Thread(); void start(); //调用start,新建的线程开始执行ThreadFunc函数。 int join(); // return pthread_join() bool started() const { return started_; } // pthread_t pthreadId() const { return pthreadId_; } pid_t tid() const { return *tid_; } const string& name() const { return name_; } static int numCreated() { return numCreated_.get(); } private: void setDefaultName(); bool started_; bool joined_; pthread_t pthreadId_; boost::shared_ptr<pid_t> tid_; ThreadFunc func_; string name_;};}Thread::Thread(ThreadFunc&& func, const string& n) : started_(false), joined_(false), pthreadId_(0), tid_(new pid_t(0)), func_(std::move(func)), name_(n){ setDefaultName();}Thread::~Thread(){ if (started_ && !joined_) { pthread_detach(pthreadId_); }}void Thread::start() //创建一个线程{ assert(!started_); started_ = true; // FIXME: move(func_) detail::ThreadData* data = new detail::ThreadData(func_, name_, tid_); if (pthread_create(&pthreadId_, NULL, &detail::startThread, data)) { started_ = false; delete data; // or no delete? LOG_SYSFATAL << "Failed in pthread_create"; }}int Thread::join() //创建该线程的线程可以调用join,等待线程退出{ assert(started_); assert(!joined_); joined_ = true; return pthread_join(pthreadId_, NULL);}
Thred线程类的使用:
Thread thread(func,”thread”); //实例化一个线程对象,其中func是一个函数指针
thread.start(); //创建一个线程,并开始执行
2,EventLoopThread类封装一个EventLoop线程,即对Thread的进一步封装
class EventLoopThread : boost::noncopyable{ public: typedef boost::function<void(EventLoop*)> ThreadInitCallback;//线程初始化回调 EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback(), const string& name = string()); ~EventLoopThread(); EventLoop* startLoop(); //开始 private: void threadFunc(); EventLoop* loop_; bool exiting_; Thread thread_; MutexLock mutex_; Condition cond_; ThreadInitCallback callback_;};//EventLoopThread 构造函数会创建一个thread.EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, const string& name) : loop_(NULL), exiting_(false), thread_(boost::bind(&EventLoopThread::threadFunc, this), name), mutex_(), cond_(mutex_), callback_(cb){}EventLoopThread::~EventLoopThread(){ exiting_ = true; if (loop_ != NULL) // not 100% race-free, eg. threadFunc could be running callback_. { // still a tiny chance to call destructed object, if threadFunc exits just now. // but when EventLoopThread destructs, usually programming is exiting anyway. loop_->quit(); thread_.join(); }}//调用该函数会调用thread.start()-》EventLoopThread::threadFunc()ThreadFunc()->实例化一个EventLoop-》return loop_;EventLoop* EventLoopThread::startLoop(){ assert(!thread_.started()); thread_.start(); { MutexLockGuard lock(mutex_); while (loop_ == NULL) { cond_.wait(); } } return loop_;}void EventLoopThread::threadFunc()// thread_.start();会执行该函数,并且在线程内实例化一个新的EventLoop实例,并会停留在loop.loop();{ EventLoop loop; if (callback_) { callback_(&loop); } { MutexLockGuard lock(mutex_); loop_ = &loop; cond_.notify(); } loop.loop(); //assert(exiting_); loop_ = NULL;}
EventLoopThread类的使用:
EventLoopThread eventloopthread;//实例化一个EventLoopThread,没有ThreadInitCallback
EventLoop* ioloop = eventloopthread.startLoop();
//执行该线程的线程将会创建一个新的线程,这个新的线程有一个自己的EventLoop,并且会返回他的EventLoop对象的指针。即新线程的EventLoop对象是暴露给父线程的。
3,EventLoopThreadPool是管理EventLoopThread的池。
EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg) : baseLoop_(baseLoop), //baseLoop为主线程拥有的EventLoop; name_(nameArg), started_(false), numThreads_(0), //该线程池需要创建的线程个数 next_(0){}EventLoopThreadPool::~EventLoopThreadPool(){ // Don't delete loop, it's stack variable}//该函数会创建 numThreads_个EventLoopThread对象并运行各个线程,并在主线程保存创建的EventLoopThread对象和EventLoopThread线程创建的EventLoop对象。如果创建的线程为0,则执行cb(baseLoop_);void EventLoopThreadPool::start(const ThreadInitCallback& cb) { assert(!started_); baseLoop_->assertInLoopThread(); started_ = true; for (int i = 0; i < numThreads_; ++i) { char buf[name_.size() + 32]; snprintf(buf, sizeof buf, "%s%d", name_.c_str(), i); EventLoopThread* t = new EventLoopThread(cb, buf); threads_.push_back(t); loops_.push_back(t->startLoop()); } if (numThreads_ == 0 && cb) { cb(baseLoop_); }}//调用该函数会按照轮流的顺序返回池里的线程的EventLoop对象指针EventLoop* EventLoopThreadPool::getNextLoop(){ baseLoop_->assertInLoopThread(); assert(started_); EventLoop* loop = baseLoop_; if (!loops_.empty()) { // round-robin loop = loops_[next_]; ++next_; if (implicit_cast<size_t>(next_) >= loops_.size()) { next_ = 0; } } return loop;} void EventLoopThreadPool::setThreadNum(int numThreads) { numThreads_ = numThreads; }
EventLoopThreadPool类的使用:
EventLoop el;EventLoopThreadPool eltp(el);eltp.setThreadNum(5);eltp.start();
0 0
- muduo源码分析--线程池的实现
- muduo源码分析:线程池类ThreadPool
- muduo源码分析--EventLoop 类的实现
- [Muduo网络库源码分析] (10) base/ThreadPoll_cc_h_线程池
- Muduo库源码分析(7):线程池
- muduo源码分析--buffer中的线程安全
- muduo源码分析:线程类Thread封装
- muduo源码分析之多线程TcpServer
- muduo源码分析之EventLoop、Channel、Poller的实现
- muduo源码分析之定时器TimerQueue的设计与实现
- muduo源码分析--我对muduo的理解
- muduo源码分析--我对muduo的理解
- muduo网络库学习笔记(5):线程池的实现
- muduo库中对线程池的实现(1)
- muduo库中对线程池的实现(2)
- muduo源码分析--连接的断开
- muduo源码分析:线程特定/私有数据类ThreadLocal
- muduo库源码分析(4):线程类
- C# 生成Excel文件及表格内容格式编辑 excel模板流
- HAUTOJ 玲珑杯 1269: 爱看电视的LsF(暴力)
- Failed to get D-Bus connection: Operation not permitted
- php,lable--for属性
- Python的类方法,对象方法,静态方法
- muduo源码分析--线程池的实现
- request.getSession(true) request.getSession(false) request.getSession()
- Android 内存泄漏总结(超级实用)
- cookie(会话cookie和持久化cookie) 和 session 以及 在爬虫登录抓取的理解
- c# DevExpress.XtraTreeList 树形节点的上下移动
- 第四讲 任务配置
- git与github简明介绍
- ubuntu 解决.txt中文乱码
- ffmpeg源码简析(十一)libavformat,libavcodec,libavutil