muduo网络库源码解析 七

26 篇文章 1 订阅

这一章节,我们来分析多线程TcpServer,首先分析muduo one loop per thread的基石——EventLoopThread class,EventLoopThread会启动自己的线程,并在其中运行EventLoop::loop(),关键的startLoop()函数定义如下,此函数会返回新线程中的EventLoop对象的地址:

EventLoop* EventLoopThread::startLoop()
{
	assert(started_ == false);
	started_ = true;
	{
		std::unique_lock<mutex> ulck(mutex_);
		while(loop_ == NULL)
		{
			cond_.wait(ulck);
		}
	}
	return loop_;
}
由于EventLoop是在新线程中建立的,而在构造函数中,新线程是threadFunc:

EventLoopThread::EventLoopThread()
	:loop_(NULL),
	 exiting_(false),
	 started_(false),
 	 thread_(std::bind(&EventLoopThread::threadFunc,this)),
	 mutex_(),
	 cond_()
{
}
因此,在startLoop中需要用条件变量等待EventLoop的建立,直到新线程中EventLoop变量的建立并赋值给loop_成员变量:

void EventLoopThread::threadFunc()
{
	EventLoop loop;
	{
		std::unique_lock<mutex> ulck(mutex_);
		loop_ = &loop;
		cond_.notify_one();
	}
	std::cout<<"thread id:"<<std::this_thread::get_id()<<"\n";
	loop_->loop();
}
之后,如果想要在新线程中添加任务,要么添加channel,要么使用runInLoop函数。由于EventLoop是局部变量,threadFunc函数结束后,变量就失效。

接着我们来分析一下EventLoopThreadPool。用one loop per thread思想实现多线程TcpServer的关键步骤是在新建的TcpConnection时从event loop pool里挑选一个loop给TcpConnection用。就是说多线程TcpServer自己的EventLoop只用来接受新连接,而新连接会用其他EventLoop来执行IO,EventLoopThreadPool类定义如下:

class EventLoopThreadPool : boost::noncopyable
{
 public:
  EventLoopThreadPool(EventLoop* baseLoop);
  ~EventLoopThreadPool();
  void setThreadNum(int numThreads) { numThreads_ = numThreads; }
  void start();
  EventLoop* getNextLoop();

 private:
  EventLoop* baseLoop_;
  bool started_;
  int numThreads_;
  int next_;  // always in loop thread
  boost::ptr_vector<EventLoopThread> threads_;
  std::vector<EventLoop*> loops_;
};
其中start函数用来向loops_内添加内容(由于都是nocopyable,所以智能拷贝指针),最主要的函数是getNextLoop:

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

  if (!loops_.empty())
  {
    // round-robin
    loop = loops_[next_];
    ++next_;
    if (static_cast<size_t>(next_) >= loops_.size())
    {
      next_ = 0;
    }
  }
  return loop;
}
记录一个next_下标,采用轮询的方式返回pool中的EventLoopThread,每个TcpServer都有自己的EventLoopThreadPool。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值