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;
}
上一篇下一篇

猜你喜欢

热点阅读