美文网首页浅析muduo网络库程序员
浅析muduo网络库之EventLoopThreadPool

浅析muduo网络库之EventLoopThreadPool

作者: 谢昆明 | 来源:发表于2018-01-10 16:21 被阅读144次

1 上代码

class EventLoopThreadPool : boost::noncopyable
{
 public:
  typedef boost::function<void(EventLoop*)> ThreadInitCallback;

  EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg);

  void setThreadNum(int numThreads) { numThreads_ = numThreads; }
  void start(const ThreadInitCallback& cb = ThreadInitCallback());
  //........
}

这是比较关键的几个函数,可以这么用

EventLoop loop;
// 创建线程池
EventLoopThreadPool pool(&loop, "");
// 设置线程个数
poll.setThreadNum(100);
// 启动线程池
poll.start();

2 看看实现细节

2.1 ctor


EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
  : baseLoop_(baseLoop),
    name_(nameArg),
    started_(false),
    numThreads_(0),
    next_(0)
{
}

简单明了,初始化成员变量

2.2 start


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

这个其实可以分两段看,numThreads_是否为0

2.2.1 numThreads_不为0

for循环
1)创建线程
EventLoopThread* t = new EventLoopThread(cb, buf);
2)保存线程
threads_.push_back(t);
3)保存线程对应的EventLoop
loops_.push_back(t->startLoop());

2.2.2 numThreads_为0

调用回调函数
cb(baseLoop_);

3 很好。那我怎么把任务放进线程池

如果各位每一篇文章都看下来的话,会发现一件事情——每个构造函数都需要传递一个EventLoop
explicit TimerQueue(EventLoop* loop);

代码可以这么写,接上面的poll

TimerQueue timer_queue(poll.getNextLoop());
timer_queue.addTimer(...)

也就是说,任务在哪个EventLoop运行,这个负载需要自己决定。

3.0 代码提供了三个方法获取EventLoop

  // valid after calling start()
  /// round-robin
  EventLoop* getNextLoop();

  /// with the same hash code, it will always return the same EventLoop
  EventLoop* getLoopForHash(size_t hashCode);

  std::vector<EventLoop*> getAllLoops();

3.1 循环获取EventLoop

EventLoop* getNextLoop();

3.2 根据hashCode获取EventLoop

EventLoop* getLoopForHash(size_t hashCode);
hashCode哪里来的,头文件没有提供生成hashCode的方法——那就随便

EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode)
{
  baseLoop_->assertInLoopThread();
  EventLoop* loop = baseLoop_;

  if (!loops_.empty())
  {
    loop = loops_[hashCode % loops_.size()];
  }
  return loop;
}

确实可以随便写
loop = loops_[hashCode % loops_.size()];

3.3 一次获取所有的EventLoop

std::vector<EventLoop*> getAllLoops();

打赏

如果这篇文章解决了您的问题,让我买根烟抽抽。

支付宝.jpg 微信.jpg

相关文章

网友评论

    本文标题:浅析muduo网络库之EventLoopThreadPool

    本文链接:https://www.haomeiwen.com/subject/wdqonxtx.html