简介
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 <functional>
#include <memory>
#include <vector>
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 <stdio.h>
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_;
}
}