one loop per thread

muduo中,one loop per thread即一个线程中一个loop循环。

这个线程是EventLoopThread对象, 这个循环就是其成员EventLoop对象调用的loop()循环,由这个循环来进行等待事件就绪并分发到各自的事件处理函数。EventLoopThread对象由线程池EventLoopThreadPool管理,每个EventLoopThread对象都有一个EventLooploop()运行其中。

调用void EventLoopThreadPool::start(const ThreadInitCallback& cb)创建线程并运行事件循环。

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

t->startLoop()thread_.start()会启动线程,这个线程函数就是EventLoopThread::threadFunc()
EventLoop* EventLoopThread::startLoop()需要返回loop,但是必须等待子线程中完成对loop_的赋值。所以必须等待cond_.wait();,
当子线程完成loop_的赋值后,马上进行通知cond_.notify();

EventLoop* EventLoopThread::startLoop()
{
	assert(!thread_.started());
	thread_.start();

	EventLoop* loop = NULL;
	{
		MutexLockGuard lock(mutex_);
		while (loop_ == NULL)
		{
			cond_.wait();
		}
		loop = loop_;
	}

	return loop;
}
void EventLoopThread::threadFunc()
{
  EventLoop loop;

  if (callback_)
  {
    callback_(&loop);
  }

  {
    MutexLockGuard lock(mutex_);
    loop_ = &loop; // 
    cond_.notify();
  }

  loop.loop();
  //assert(exiting_);
  MutexLockGuard lock(mutex_);
  loop_ = NULL;
}

之后所有的EventLoop对象就全部存储在EventLoopThreadPool的成员loops_中。

当需要取得一个EventLoop对象时,调用EventLoop* EventLoopThreadPool::getNextLoop()获取,其中使用了简单的Round Robin调度算法。

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

你可能感兴趣的:(muduo)