muduo源码分析--线程池的实现

muduo线程池主要有3个类的实现:EventLoop,EventLoopThreadPool,EventLoopThread,和Thread.
1.Thread为对一个线程的封装:

class Thread : boost::noncopyable
{
 public:
  typedef boost::function<void ()> ThreadFunc;   //创建线程时,传递的函数

  explicit Thread(const ThreadFunc&, const string& name = string());
#ifdef __GXX_EXPERIMENTAL_CXX0X__
  explicit Thread(ThreadFunc&&, const string& name = string());
#endif
  ~Thread();

  void start();   //调用start,新建的线程开始执行ThreadFunc函数。
  int join(); // return pthread_join()

  bool started() const { return started_; }
  // pthread_t pthreadId() const { return pthreadId_; }
  pid_t tid() const { return *tid_; }
  const string& name() const { return name_; }

  static int numCreated() { return numCreated_.get(); }

 private:
  void setDefaultName();

  bool       started_;
  bool       joined_;
  pthread_t  pthreadId_;
  boost::shared_ptr<pid_t> tid_;
  ThreadFunc func_;
  string     name_;
};
}
Thread::Thread(ThreadFunc&& func, const string& n)
  : started_(false),
    joined_(false),
    pthreadId_(0),
    tid_(new pid_t(0)),
    func_(std::move(func)),
    name_(n)
{
  setDefaultName();
}
Thread::~Thread()
{
  if (started_ && !joined_)
  {
    pthread_detach(pthreadId_);
  }
}
void Thread::start()   //创建一个线程
{
  assert(!started_);
  started_ = true;
  // FIXME: move(func_)
  detail::ThreadData* data = new detail::ThreadData(func_, name_, tid_);
  if (pthread_create(&pthreadId_, NULL, &detail::startThread, data))
  {
    started_ = false;
    delete data; // or no delete?
    LOG_SYSFATAL << "Failed in pthread_create";
  }
}

int Thread::join()  //创建该线程的线程可以调用join,等待线程退出
{
  assert(started_);
  assert(!joined_);
  joined_ = true;
  return pthread_join(pthreadId_, NULL);
}

Thred线程类的使用:
Thread thread(func,”thread”); //实例化一个线程对象,其中func是一个函数指针
thread.start(); //创建一个线程,并开始执行

2,EventLoopThread类封装一个EventLoop线程,即对Thread的进一步封装

class EventLoopThread : boost::noncopyable
{
 public:
  typedef boost::function<void(EventLoop*)> ThreadInitCallback;//线程初始化回调

  EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback(),
                  const string& name = string());
  ~EventLoopThread();
  EventLoop* startLoop();   //开始

 private:
  void threadFunc();

  EventLoop* loop_;
  bool exiting_;
  Thread thread_;
  MutexLock mutex_;
  Condition cond_;
  ThreadInitCallback callback_;
};
//EventLoopThread 构造函数会创建一个thread.
EventLoopThread::EventLoopThread(const ThreadInitCallback& cb,
                                 const string& name)
  : loop_(NULL),
    exiting_(false),
    thread_(boost::bind(&EventLoopThread::threadFunc, this), name),
    mutex_(),
    cond_(mutex_),
    callback_(cb)
{
}

EventLoopThread::~EventLoopThread()
{
  exiting_ = true;
  if (loop_ != NULL) // not 100% race-free, eg. threadFunc could be running callback_.
  {
    // still a tiny chance to call destructed object, if threadFunc exits just now.
    // but when EventLoopThread destructs, usually programming is exiting anyway.
    loop_->quit();
    thread_.join();
  }
}
//调用该函数会调用thread.start()-》EventLoopThread::threadFunc()ThreadFunc()->实例化一个EventLoop-》return loop_;
EventLoop* EventLoopThread::startLoop()
{
  assert(!thread_.started());
  thread_.start();

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

  return loop_;
}

void EventLoopThread::threadFunc()// thread_.start();会执行该函数,并且在线程内实例化一个新的EventLoop实例,并会停留在loop.loop();
{
  EventLoop loop;

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

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

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

EventLoopThread类的使用:
EventLoopThread eventloopthread;//实例化一个EventLoopThread,没有ThreadInitCallback
EventLoop* ioloop = eventloopthread.startLoop();
//执行该线程的线程将会创建一个新的线程,这个新的线程有一个自己的EventLoop,并且会返回他的EventLoop对象的指针。即新线程的EventLoop对象是暴露给父线程的。

3,EventLoopThreadPool是管理EventLoopThread的池。

EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
  : baseLoop_(baseLoop),    //baseLoop为主线程拥有的EventLoop;
    name_(nameArg),        
    started_(false),
    numThreads_(0),        //该线程池需要创建的线程个数
    next_(0)
{
}

EventLoopThreadPool::~EventLoopThreadPool()
{
  // Don't delete loop, it's stack variable
}
//该函数会创建 numThreads_个EventLoopThread对象并运行各个线程,并在主线程保存创建的EventLoopThread对象和EventLoopThread线程创建的EventLoop对象。如果创建的线程为0,则执行cb(baseLoop_);
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(t);
    loops_.push_back(t->startLoop());
  }
  if (numThreads_ == 0 && cb)
  {
    cb(baseLoop_);
  }
}
//调用该函数会按照轮流的顺序返回池里的线程的EventLoop对象指针
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;
}
  void EventLoopThreadPool::setThreadNum(int numThreads) { numThreads_ = numThreads; }

EventLoopThreadPool类的使用:

EventLoop el;
EventLoopThreadPool eltp(el);
eltp.setThreadNum(5);
eltp.start();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值