muduo源码学习(18)-EventLoopThread

来源:互联网 发布:淘宝神笔在哪里打开 编辑:程序博客网 时间:2024/06/05 12:50

EventLoop是对循环的封装,并且每一个线程最多只能有一个EventLoop对象,在该线程中运行loop函数。为了更方便的将线程与EventLoop结合,muduo中封装了EventLoopTheread类。在net/EventLoopThread.h中:

class EventLoop;class EventLoopThread : boost::noncopyable{ public:  typedef boost::function<void(EventLoop*)> ThreadInitCallback;  EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback());  ~EventLoopThread();  EventLoop* startLoop(); private:  void threadFunc();  EventLoop* loop_;  bool exiting_;    Thread thread_;  MutexLock mutex_;  Condition cond_;  ThreadInitCallback callback_;};
该类中有线程类,锁,条件变量,EventLoop指针。实现如下:

//EventLoopThread::EventLoopThread(const ThreadInitCallback& cb)  : loop_(NULL),    exiting_(false),    //线程初始化    thread_(boost::bind(&EventLoopThread::threadFunc, this)),    mutex_(),    cond_(mutex_),    callback_(cb){}EventLoopThread::~EventLoopThread(){  exiting_ = true;  loop_->quit();  thread_.join();}//启动线程EventLoop* EventLoopThread::startLoop(){  assert(!thread_.started());  thread_.start();  {    MutexLockGuard lock(mutex_);//需要等待    while (loop_ == NULL)    {      cond_.wait();    }  }//返回创建的loop  return loop_;}//线程中运行的函数void EventLoopThread::threadFunc(){//创建EventLoop对象  EventLoop loop;  if (callback_)  {    callback_(&loop);  }  {    MutexLockGuard lock(mutex_);    loop_ = &loop;    cond_.notify();  }  loop.loop();  //assert(exiting_);}

该类主要函数就是startLoop,在该函数中,运行了线程,而在线程入口函数threadFunc中创建了EventLoop对象。在startLoop中,存在两个线程,因此EventLoop的创建以及赋值给loop_和返回loop_是不确定的,因此主线程需要等待loop_被赋值后再返回,这也是需要条件变量的原因。在该类中,还有一个callback回调函数,可以不使用,类似于钩子。loop_指向在子线程中的局部变量loop,但由于子线程一直处于循序中,因此不会造成空悬指针。