• muduo源码剖析之EventLoopThread


    简介

    EventLoopThread类包装了一个thread类和一个EventLoop类,(one loop per thread)是封装了一个EventLoop的独立线程

    主要成员及属性解析

    意为I/O线程类,EventLoopThread可以创建一个IO线程,通过startLoop返回一个IO线程的loop,threadFunc中开启loop循环,

    源码剖析

    这个类比较简单,代码都写了注释,不多说

    EventLoopThread.h

    #ifndef MUDUO_NET_EVENTLOOPTHREAD_H
    #define MUDUO_NET_EVENTLOOPTHREAD_H
    
    #include "muduo/base/Condition.h"
    #include "muduo/base/Mutex.h"
    #include "muduo/base/Thread.h"
    
    namespace muduo
    {
    namespace net
    {
    
    class EventLoop;
    
    class EventLoopThread : noncopyable
    {
     public:
      typedef std::function<void(EventLoop*)> ThreadInitCallback;
    
      EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback(),
                      const string& name = string());
      ~EventLoopThread();
      EventLoop* startLoop();//通过此接口启动io线程,返回subloop
    
     private:
      void threadFunc();//线程调用函数,进入loop
    
      EventLoop* loop_ GUARDED_BY(mutex_);//subloop
      bool exiting_;//loop退出标志
      Thread thread_;
      MutexLock mutex_;
      Condition cond_ GUARDED_BY(mutex_);
      ThreadInitCallback callback_;//线程初始化时调用的函数,不设置则不会调用
    };
    
    }  // namespace net
    }  // namespace muduo
    
    #endif  // MUDUO_NET_EVENTLOOPTHREAD_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    EventLoopThread.cc

    // Copyright 2010, Shuo Chen.  All rights reserved.
    // http://code.google.com/p/muduo/
    //
    // Use of this source code is governed by a BSD-style license
    // that can be found in the License file.
     
    // Author: Shuo Chen (chenshuo at chenshuo dot com)
     
    #include "muduo/net/EventLoopThread.h"
     
    #include "muduo/net/EventLoop.h"
     
    using namespace muduo;
    using namespace muduo::net;
     
    EventLoopThread::EventLoopThread(const ThreadInitCallback& cb,
                                     const string& name)
      : loop_(NULL),      //loop未启动为NULL
        exiting_(false),	//
        thread_(std::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();   //等待线程退出
      }
    }
     
    EventLoop* EventLoopThread::startLoop()
    {
      assert(!thread_.started());
      thread_.start(); //调用pthread_create创建线程,此时有两个线程在运行
      //一个是调用EventLoopThread::startLoop()的线程,一个是执行EventLoopThread::threadFunc()的线程(IO线程)
     
      EventLoop* loop = NULL;
      {
        MutexLockGuard lock(mutex_);
        while (loop_ == NULL)
        {
          cond_.wait();     //须要等待EventLoop对象的创建
        }
        loop = loop_;       //IO线程创建loop_赋给主线程
      }
      
      return loop;          //主线程返回IO线程创建的EventLoop对象
    }
     
    void EventLoopThread::threadFunc()            //创建线程时会调用这个函数
    {
      EventLoop loop;       //IO线程也要创建EventLoop对象,还要通知主线程已经创建完毕
     
      if (callback_)//如果设置了cb则diao'y
      {
        callback_(&loop);     //将定义好的loop传入回调
      }
     
      {
        MutexLockGuard lock(mutex_);
        // loop_指针指向了一个栈上的对象,threadFunc函数退出之后。这个指针就失效了
        // threadFunc函数退出,就意味着线程退出了,EventLoopThread对象也就没有存在的价值了
        // 因而不会有什么大的问题
        loop_ = &loop;
        cond_.notify();     //创建好,发送通知
      }
     
      loop.loop();          // 会在这里循环,直到EventLoopThread析构。此后不再使用loop_訪问EventLoop了
      //assert(exiting_);
      MutexLockGuard lock(mutex_);
      loop_ = NULL;
    }
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    .NET Emit 入门教程:第六部分:IL 指令:6:详解 ILGenerator 指令方法:方法调用指令
    考虑车轮纵向滑动的无人自行车平衡控制实现
    JAVA&SSM&mysql面向高校校园体育用品租借管理系统94593-计算机毕业设计项目选题推荐(附源码)
    【目标检测经典算法】R-CNN、Fast R-CNN和Faster R-CNN详解系列一:R-CNN图文详解
    nvidia drive-agx-orin Driveos NVSIPL框架-内核层理解
    Java市场真的饱和了吗?
    现货黄金技术培训:减少无谓
    vue3中多层嵌套的JSON中的内容
    22.3D等距社交媒体菜单的悬停特效
    Blob 对象实现文件预览下载
  • 原文地址:https://blog.csdn.net/weixin_50448879/article/details/134021979