[muduo网络库]——muduo库EventLoopThread类(剖析muduo网络库核心部分、设计思想)

接着之前我们[muduo网络库]——muduo库Thread类(剖析muduo网络库核心部分、设计思想),我们接下来继续看muduo库中的EventLoopThread类,它和Thread类息息相关。

EventLoopThread类

封装了eventloop线程也就是IO线程,eventloopthread会启动自己的线程,并在里面运行eventloop::loop()。

重要成员变量

EventLoop *loop_;  //线程内部的eventloop*
bool exiting_;     //线程是否退出
Thread thread_;   //线程
std::mutex mutex_; //互斥锁
std::condition_variable cond_; //条件变量
ThreadInitCallback callback_; //线程初始化回调函数
  • 作用如注释所示

重要成员函数

  • 先来看看构造函数和析构函数
EventLoopThread::EventLoopThread(const ThreadInitCallback &cb ,
        const std::string &name)
        : loop_(nullptr)
        , exiting_(false)
        , thread_(std::bind(&EventLoopThread::threadFunc,this),name)
        , mutex_()
        , cond_()
        , callback_(cb)
        {

        }
EventLoopThread::~EventLoopThread()
{
    exiting_ = true;
    if(loop_ != nullptr)
    {
        loop_->quit();
        thread_.join();
    }
}
  1. 初始化给loop_为空,exiting_为否
  2. 注意thread_线程函数是threadFunc
  3. 析构函数中调用EventLoop::quit()Thread::join()
  4. callback_设置为cb
  • 启动一个Loop
EventLoop* EventLoopThread::startLoop()
{
    thread_.start(); //启动底层新线程
    EventLoop *loop =nullptr; 
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while(loop_==nullptr)
        {
            cond_.wait(lock);
        }
        loop = loop_;       
    }
    return loop;
}

void EventLoopThread::threadFunc()
{
    EventLoop loop;
    if(callback_)
    {
        callback_(&loop);
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;
        cond_.notify_one();
    }

    loop.loop(); //EventLoop loop => Poller.poll
    std::unique_lock<std::mutex> lock(mutex_);
    loop_=nullptr;
}
  1. 首先,在startLoop中调用了Thread::start(),而这里的thread_的线程函数是threadFunc,在上一篇剖析Thread类时,我们在Thread::start(),看到了一个线程函数func_(),所以func就是构造函数中&EventLoopThread::threadFunc,this 传入的,所以这里会创建线程调用threadFunc()函数,并且主线程阻塞等待EventLoop对象的创建
  2. 此时有两个线程在运行 一个是调用EventLoopThread::startLoop()的线程,一个是执行EventLoopThread::threadFunc()的线程 IO线程
  3. threadFunc是在单独的新线程里面运行的,创建一个独立的Eventloop,和上面的线程是一一对应的 one loop per thread
  4. 将IO线程定义好的loop传入回调
  5. 创建好loop了唤醒主线程,并把loop_给主线程,主线程返回IO线程创建的EventLoop对象
  6. 注意开始执行 loop.loop();,也就是EventLoop loop => Poller.poll,开始一个循环,知道循环结束eventloop析构,把loop_设为空。
总体来说,EventLoopThread提供了对应eventloop和thread的封装,意为I/O线程类,EventLoopThread可以创建一个IO线程,通过startLoop返回一个IO线程的loop,threadFunc中开启loop循环。

补充一下条件变量condition_variable

头文件 #include <condition_variable>
两种形式
  • condition_variable
  • ​condition_variable_any
    相同点:两者都能与std::mutex一起使用。
    不同点:前者仅限于与 std::mutex 一起工作,而后者可以和任何满足最低标准的互斥量一起工作,从而加上了_any的后缀。condition_variable_any会产生额外的开销。
std::condition_variable::wait()

当条件对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。通常使用 std::unique_lockstd::mutex 来等待,当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程,该函数会自动调用 lck.unlock() 释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。

std::condition_variable::wait_for()

可以指定一个时间段,在当前线程收到通知或者指定的时间 rel_time 超时之前,该线程都会处于阻塞状态。而一旦超时或者收到了其他线程的通知,wait_for 返回,剩下的处理步骤和 wait() 类似。

std::condition_variable::notify_one()

唤醒某个等待(wait)线程。如果当前没有等待线程,则该函数什么也不做,如果同时存在多个等待线程,则唤醒某个线程是不确定的(unspecified)。

std::condition_variable::notify_all()

唤醒所有的等待(wait)线程。如果当前没有等待线程,则该函数什么也不做。

代码地址:https://github.com/Cheeron955/mymuduo/tree/master

好了~ 关于muduo库的EventLoopThread类就剖析到这里,要记住里面涉及到的 one loop per thread ,最后,下一篇我们来剖析和这两类息息相关的EventLoopThreadPool类 ~ 我们下一节见 ~~

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值