您的位置:首页 > 运维架构

muduo库阅读(36)——Net部分:事件循环线程池EventLoopThreadPool

2015-11-11 21:51 525 查看
/*
* 事件循环线程池
* 这个类适用于一个进程中存在多个Reactor实例的情况
*/
namespace muduo
{

namespace net
{

class EventLoop;
class EventLoopThread;

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

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

// 设置线程池的线程数量
void setThreadNum(int numThreads) { numThreads_ = numThreads; }

// 启动线程池
void start(const ThreadInitCallback& cb = ThreadInitCallback());

// 获取下一个EventLoop对象
EventLoop* getNextLoop();

// 根据一个哈希码返回一个EventLoop对象
EventLoop* getLoopForHash(size_t hashCode);

// 获取所有的EventLoop对象
std::vector<EventLoop*> getAllLoops();

// 判断线程池是否已经启动
bool started() const
{ return started_; }

// 线程池的名字
const string& name() const
{ return name_; }

private:

//主要的EventLoop对象
EventLoop* baseLoop_;

// 线程池的名字
string name_;

// 线程池是否已经启动
bool started_;

// 线程池中线程的数量
int numThreads_;
int next_;

// 线程列表
boost::ptr_vector<EventLoopThread> threads_;

// EventLoop对象列表
std::vector<EventLoop*> loops_;
};

}
}


using namespace muduo;
using namespace muduo::net;

/*
* 构造函数
*/
EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
: baseLoop_(baseLoop),
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(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;
}

// 根据哈希码获取一个EventLoop对象,其实哈希码就是EventLoop数组的下标
EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode)
{
baseLoop_->assertInLoopThread();
EventLoop* loop = baseLoop_;

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

// 获取所有的EventLoop对象
std::vector<EventLoop*> EventLoopThreadPool::getAllLoops()
{
baseLoop_->assertInLoopThread();
assert(started_);
if (loops_.empty())
{
return std::vector<EventLoop*>(1, baseLoop_);
}
else
{
return loops_;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: