美文网首页浅析muduo网络库程序员
浅析muduo网络库之EventLoopThreadPool

浅析muduo网络库之EventLoopThreadPool

作者: 谢昆明 | 来源:发表于2018-01-10 16:21 被阅读144次

    1 上代码

    class EventLoopThreadPool : boost::noncopyable
    {
     public:
      typedef boost::function<void(EventLoop*)> ThreadInitCallback;
    
      EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg);
    
      void setThreadNum(int numThreads) { numThreads_ = numThreads; }
      void start(const ThreadInitCallback& cb = ThreadInitCallback());
      //........
    }
    

    这是比较关键的几个函数,可以这么用

    EventLoop loop;
    // 创建线程池
    EventLoopThreadPool pool(&loop, "");
    // 设置线程个数
    poll.setThreadNum(100);
    // 启动线程池
    poll.start();
    

    2 看看实现细节

    2.1 ctor

    
    EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
      : baseLoop_(baseLoop),
        name_(nameArg),
        started_(false),
        numThreads_(0),
        next_(0)
    {
    }
    

    简单明了,初始化成员变量

    2.2 start

    
    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_);
      }
    }
    

    这个其实可以分两段看,numThreads_是否为0

    2.2.1 numThreads_不为0

    for循环
    1)创建线程
    EventLoopThread* t = new EventLoopThread(cb, buf);
    2)保存线程
    threads_.push_back(t);
    3)保存线程对应的EventLoop
    loops_.push_back(t->startLoop());

    2.2.2 numThreads_为0

    调用回调函数
    cb(baseLoop_);

    3 很好。那我怎么把任务放进线程池

    如果各位每一篇文章都看下来的话,会发现一件事情——每个构造函数都需要传递一个EventLoop
    explicit TimerQueue(EventLoop* loop);

    代码可以这么写,接上面的poll

    TimerQueue timer_queue(poll.getNextLoop());
    timer_queue.addTimer(...)
    

    也就是说,任务在哪个EventLoop运行,这个负载需要自己决定。

    3.0 代码提供了三个方法获取EventLoop

      // valid after calling start()
      /// round-robin
      EventLoop* getNextLoop();
    
      /// with the same hash code, it will always return the same EventLoop
      EventLoop* getLoopForHash(size_t hashCode);
    
      std::vector<EventLoop*> getAllLoops();
    

    3.1 循环获取EventLoop

    EventLoop* getNextLoop();

    3.2 根据hashCode获取EventLoop

    EventLoop* getLoopForHash(size_t hashCode);
    hashCode哪里来的,头文件没有提供生成hashCode的方法——那就随便

    EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode)
    {
      baseLoop_->assertInLoopThread();
      EventLoop* loop = baseLoop_;
    
      if (!loops_.empty())
      {
        loop = loops_[hashCode % loops_.size()];
      }
      return loop;
    }
    

    确实可以随便写
    loop = loops_[hashCode % loops_.size()];

    3.3 一次获取所有的EventLoop

    std::vector<EventLoop*> getAllLoops();

    打赏

    如果这篇文章解决了您的问题,让我买根烟抽抽。

    支付宝.jpg 微信.jpg

    相关文章

      网友评论

        本文标题:浅析muduo网络库之EventLoopThreadPool

        本文链接:https://www.haomeiwen.com/subject/wdqonxtx.html