muduo
中,one loop per thread
即一个线程中一个loop循环。
这个线程是EventLoopThread
对象, 这个循环就是其成员EventLoop
对象调用的loop()循环,由这个循环来进行等待事件就绪并分发到各自的事件处理函数。EventLoopThread
对象由线程池EventLoopThreadPool
管理,每个EventLoopThrea
d对象都有一个EventLoop
的loop()
运行其中。
调用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;
}