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

来源:互联网 发布:淘宝友情链接 编辑:程序博客网 时间:2024/05/16 05:52

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 0
原创粉丝点击