muduo源码剖析之EventLoopThreadPool

简介

EventLoopThreadPool是EventLoopThread类的线程池类

封装了若干个EventLoopThread的线程池,所有者是一个外部的EventLoop

EventLoopThreadPool == EventLoopThread + vector

主要成员及属性解析

通过调用start函数来new EventLoopThread创建对应的线程和其loop,并将创建的保存在vector中

源码剖析

这个类比较简单,代码都写了注释,不多说

EventLoopThreadPool.h

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
 
// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is an internal header file, you should not include this.
 
#ifndef MUDUO_NET_EVENTLOOPTHREADPOOL_H
#define MUDUO_NET_EVENTLOOPTHREADPOOL_H
 
#include "muduo/base/noncopyable.h"
#include "muduo/base/Types.h"
 
#include 
#include 
#include 
 
namespace muduo
{
 
namespace net
{
 
class EventLoop;
class EventLoopThread;
 
class EventLoopThreadPool : noncopyable
{
 public:
  typedef std::function<void(EventLoop*)> ThreadInitCallback;
 
  EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg);
  ~EventLoopThreadPool();
    
  //设置subloop的数量
  void setThreadNum(int numThreads) { numThreads_ = numThreads; }
  //线程池启动,会创建设置好的EventLoopThread数量,并保存threads_中
  void start(const ThreadInitCallback& cb = ThreadInitCallback());
 
  // valid after calling start()
  /// round-robin
  //通过next变量保存下标,每调用一次就会获取下一个loop
  EventLoop* getNextLoop();
 
  /// with the same hash code, it will always return the same EventLoop
  //使用相同的哈希码,它将始终返回相同的事件循环,
  //通过hash码获取相应的loop
  EventLoop* getLoopForHash(size_t hashCode);
 
  //获取所有的subloop
  std::vector<EventLoop*> getAllLoops();
 
  bool started() const
  { return started_; }
 
  const string& name() const
  { return name_; }
 
 private:
 
  EventLoop* baseLoop_;     //主线程的事件驱动循环,TcpServer所在的事件驱动循环,创建TcpServer传入的EventLoop
  string name_;
  bool started_;//线程池启动标志
  int numThreads_;          //线程数 
  int next_;                //标记下次应该取出哪个线程,采用round_robin
  std::vector<std::unique_ptr<EventLoopThread>> threads_;     //线程池中所有的线程 
  //线程池中每个线程对应的事件驱动循环,从线程池取出线程实际上返回的是事件驱动循环
  //每个事件驱动循环运行在一个线程中
  std::vector<EventLoop*> loops_;
};
 
}  // namespace net
}  // namespace muduo
 
#endif  // MUDUO_NET_EVENTLOOPTHREADPOOL_H

EventLoopThreadPool.cc

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
 
// Author: Shuo Chen (chenshuo at chenshuo dot com)
 
#include "muduo/net/EventLoopThreadPool.h"
 
#include "muduo/net/EventLoop.h"
#include "muduo/net/EventLoopThread.h"
 
#include 
 
using namespace muduo;
using namespace muduo::net;
 
//EventLoopThreadPool loop对应的线程池
EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
  : baseLoop_(baseLoop),//设置mainloop
    name_(nameArg),
    started_(false),
    numThreads_(0),
    next_(0)
{
}
 
EventLoopThreadPool::~EventLoopThreadPool()
{
  // Don't delete loop, it's stack variable
}
 
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(std::unique_ptr<EventLoopThread>(t));
    loops_.push_back(t->startLoop());
  }
  if (numThreads_ == 0 && cb)
  {
    cb(baseLoop_);
  }
}
 
EventLoop* EventLoopThreadPool::getNextLoop()        //获取一个线程(事件驱动循环),通常在创建TcpConnection时调用 
{
  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;
}
 
EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode)
{
  baseLoop_->assertInLoopThread();
  EventLoop* loop = baseLoop_;
 
  if (!loops_.empty())
  {
    loop = loops_[hashCode % loops_.size()];
  }
  return loop;
}
 
std::vector<EventLoop*> EventLoopThreadPool::getAllLoops()
{
  baseLoop_->assertInLoopThread();
  assert(started_);
  if (loops_.empty())
  {
    return std::vector<EventLoop*>(1, baseLoop_);
  }
  else
  {
    return loops_;
  }
}

你可能感兴趣的:(muduo源码剖析,1024程序员节,linux,服务器,后端,c语言,网络编程,muduo)