Muduo库设计(1)——什么都不做的EventLoop
2019-11-26 本文已影响0人
Magic11
1、每个线程只能创建一个Eventloop对象
int main()
{
muduo::EventLoop loop;
loop.loop();
}
EventLoop在创建的同时会获取并记录当前线程的id,并记住该thread ID。
2、如果一个线程创建了多于一个EventLoop对象,程序会退出
EventLoop如何判断在同一个线程中被多次创建?
__thread EventLoop* t_loopInThisThread = 0;
EventLoop::EventLoop() : threadId_(std::this_thread::get_id()),
{
if (t_loopInThisThread)
{
LOG_FATAL << "Another EventLoop " << t_loopInThisThread
<< " exists in this thread " /*<< threadId_*/;
}
else
{
t_loopInThisThread = this;
}
}
__thread是GCC内置的线程局部存储设施。_thread变量每一个线程有一份独立实体,各个线程的值互不干扰。
t_loopInThisThread的初始值为0,当在一个线程中创建了一个EventLoop对象时,t_loopInThisThread被赋值指向该EventLoop对象。
下次在该线程中再创建EventLoop对象时,发现t_loopInThisThread的值已不为空,表示已经创建过EventLoop对象了。
3、 EventLoop会明确出哪些成员函数只能在当前线程调用,哪些成员函数可以在别的线程中调用。
bool isInLoopThread() const {
return threadId_ == std::this_thread::get_id();
}
void assertInLoopThread()
{
if (!isInLoopThread())
{
abortNotInLoopThread();
}
}
void EventLoop::abortNotInLoopThread()
{
LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this
<< " was created in threadId_ = " /*<< threadId_*/
<< ", current thread id = " /*<< CurrentThread::tid()*/;
}
例如,其中loop函数必须在当前线程中调用
void EventLoop::loop()
{
assert(!looping_);
assertInLoopThread();
looping_ = true;
quit_ = false;
while (!quit_)
{
}
LOG_TRACE << "EventLoop " << this << " stop looping";
looping_ = false;
}