net10. IO线程池类——EventLoopThreadPool

EventLoopThreadPool类在这里插入图片描述

  1. EventLoopThreadPool是事件循环线程池,管理所有客户端连接,每个线程都有唯一一个事件循环。可以调用setThreadNum设置线程的数目。
  2. EventLoopThreadPool类又叫IO线程池类,由1个主线程+N个子线程组成,“1+N”的模式一般用在服务端,主线程用于接收所有客户端的连接请求,各子线程用于处理多个客户端的IO事件。给线程池分配客户端的时候采取循环分配的方式,保证线程池的负载平衡。多个客户端的IO操作可以对应于1个IO线程,但是1个客户端的IO操作不能对应于多个IO线程,因为多个IO线程抢占执行同一个客户端的读写操作会因为可能导致串写而需要用互斥锁。
  3. EventLoopThread作为EventLoopThreadPool的成员对象,多个EventLoopThread对象保存到std::vector中构成了EventLoopThreadPool的线程池。

数据成员:

EventLoop* baseLoop_:与Acceptor所属EventLoop相同,负责监听
bool started_:线程池是否启动
int numThreads_:线程数
int next_:新连接到来,所选择的EventLoop对象下标,选择一个线程进行处理
boost::ptr_vector<EventLoopThread> threads_:IO线程列表
std::vector<EventLoop*> loops_:EventLoop列表

typedef

typedef boost::function<void(EventLoop*)> ThreadInitCallback

成员函数:

EventLoopThreadPool(EventLoop* baseLoop):构造函数
~EventLoopThreadPool():析构函数
void setThreadNum(int numThreads):设置线程池中线程数目的大小
void start(const ThreadInitCallback& cb = ThreadInitCallback()):启动线程池
EventLoop* getNextLoop():当一个新连接到来时,选择一个新的EventLoop来处理

EventLoopThreadPool.h

// This is an internal header file, you should not include this.

#ifndef MUDUO_NET_EVENTLOOPTHREADPOOL_H
#define MUDUO_NET_EVENTLOOPTHREADPOOL_H

#include <muduo/base/Condition.h>
#include <muduo/base/Mutex.h>

#include <vector>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace muduo
{

namespace net
{

class EventLoop;
class EventLoopThread;

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

  EventLoopThreadPool(EventLoop* baseLoop);
  ~EventLoopThreadPool();
  //设置线程池中线程数目的大小
  void setThreadNum(int numThreads) { numThreads_ = numThreads; }
  //启动线程池
  void start(const ThreadInitCallback& cb = ThreadInitCallback());
  //当一个新连接到来时,选择一个新的EventLoop来处理
  EventLoop* getNextLoop();

 private:

  // 与Acceptor所属EventLoop相同,负责监听
  EventLoop* baseLoop_;	
  // 线程池是否启动
  bool started_;
  // 线程数
  int numThreads_;		
  // 新连接到来,所选择的EventLoop对象下标,选择一个线程进行处理
  int next_;			
  // IO线程列表
  boost::ptr_vector<EventLoopThread> threads_;		
  // EventLoop列表
  std::vector<EventLoop*> loops_;					
};

}
}

#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 <boost/bind.hpp>

using namespace muduo;
using namespace muduo::net;


EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop)
  : baseLoop_(baseLoop),
    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)
  {
    EventLoopThread* t = new EventLoopThread(cb);
    threads_.push_back(t);
    loops_.push_back(t->startLoop());	// 启动EventLoopThread线程,在进入事件循环之前,会调用cb
  }
  if (numThreads_ == 0 && cb)
  {
    // 只有一个EventLoop,在这个EventLoop进入事件循环之前,调用cb
    cb(baseLoop_);
  }
}

EventLoop* EventLoopThreadPool::getNextLoop()
{
  baseLoop_->assertInLoopThread();
  EventLoop* loop = baseLoop_;

  // 如果loops_为空,则loop指向baseLoop_
  // 如果不为空,按照round-robin(RR,轮叫)的调度方式选择一个EventLoop
  if (!loops_.empty())
  {
    // round-robin
    loop = loops_[next_];
    ++next_;
    if (implicit_cast<size_t>(next_) >= loops_.size())
    {
      next_ = 0;
    }
  }
  return loop;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值