muduo 19 EventLoopThread类

EventLoopThread是将EventLoop与线程封装在一起的类,确保每个线程拥有一个独立的EventLoop。在构造时,线程并不立即启动,而是在startLoop()被调用时启动。threadFunc()中创建EventLoop,并在回调函数callback_中处理。当startLoop()被调用时,它会等待线程创建并准备好EventLoop后返回。EventLoop的loop()函数执行直到服务器关闭。

目录

 

EventLoopThread事件线程类

成员变量:

 成员函数:

EventLoopThread::EventLoopThread

EventLoopThread::~EventLoopThread()

startLoop()和threadFunc():

EventLoopThread.h

EventLoopThread.cc


EventLoopThread事件线程类

        对EventLoop和thread的封装,一个线程中有一个loop,通过绑定器将其绑定。

成员变量:

 成员函数:

EventLoopThread::EventLoopThread

         对一些成员变量进行初始化,要注意的是,这里将线程通过bind绑定器绑定一个threadFunc回调函数,在该构造函数中并不会立即创建新线程,实际的线程执行是在后续startLoop函数中调用thread的start函数才进行执行的。

EventLoopThread::~EventLoopThread()

 


startLoop()和threadFunc():

EventLoop* EventLoopThread::startLoop()//开启循环
{
    thread_.start();//启动底层的新线程
	//启动后执行的是EventLoopThread::threadFunc
    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while ( loop_ == nullptr )
        {
            cond_.wait(lock);//挂起,等待  threadFunc中的loop创建好并通知
        }
        loop = loop_;
    }
    return loop;
}
void EventLoopThread::threadFunc()
{
    EventLoop loop;//创建一个独立的eventloop,和上面的线程是一一对应的,one loop per thread

    if (callback_)//如果有回调
    {
        callback_(&loop);//绑定loop做一些事情
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;//就是运行在这个线程的loop对象
        cond_.notify_one();//唤醒1个线程
    }

    // 一般来说会一直在loop函数中循环  
    loop.loop();//相当于EventLoop loop  => Poller.poll

    //执行到这个下边就说明服务器程序要关闭掉了
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}

❤这两个函数要放到一起说:

        1. 首先在startLoop函数中,调用thread_.start(),启动新线程去执行在EventLoop构造函数中绑定的threadFunc函数;

        2. 在startLoop函数中,创建一个EventLoop对象loop初始化为nullptr;

        3. 进入一个作用域,unique_lock<std::mutex> lock(mutex_)创建互斥锁;

        4. while循环检查loop_是否为nullptr,如果为空,调用cond_.wait(lock)挂起,等待其他线程通过调用cond.notufy_one()唤醒,继续执行;

        5. 其他线程调用cond.notufy_one()后,while循环退出,将loop_赋值给loop,返回loop,也即返回新线程中创建的Eventloop对象;

        6. 在threadFunc函数中,首先创建一个EventLoop对象,loop,每个线程都用有一个独立的EventLoop;

        7. 如果存在callback_,则调用callback_(&loop)去执行回调函数;

        8. 进入一个作用域,unique_lock<std::mutex> lock(mutex_)创建互斥锁,并将loop_设置为当前loop,即将新线程中创建的EventLoop对象loop赋值给loop_,然后cond.notufy_one()唤醒等待中的线程。

        9. 调用loop.loop()进入事件循环,执行EventLoop中的loop()函数;

        10. 事件循环结束后,也就是EventLoop中的loop()函数退出后,再次获取锁,将loop_设置为nullptr,表示线程结束。

        11. 返回到startLoop函数将loop返回。

        该过程实现了创建一个新线程,并在新线程中运行一个独立的 EventLoop 对象,并通过条件变量等待新线程中的 EventLoop 对象创建完成后返回,从而实现了一个 "one loop per thread" 的设计模式。

EventLoopThread.h

#pragma once

#include "noncopyable.h"
#include "Thread.h"

#include <functional>
#include <mutex>
#include <condition_variable>
#include <string>

class EventLoop;

// eventloop + thread
class EventLoopThread : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop*)>; 

    EventLoopThread(const ThreadInitCallback &cb = ThreadInitCallback(), //线程初始化的回调 
        const std::string &name = std::string());
    ~EventLoopThread();

    EventLoop* startLoop();//开启循环 
private:
    void threadFunc();//线程函数,创建loop 

    EventLoop *loop_; 
    bool exiting_;//是否退出循环 
    Thread thread_;
    std::mutex mutex_;
    std::condition_variable cond_;
    ThreadInitCallback callback_;//初始化操作 
};

EventLoopThread.cc

#include "EventLoopThread.h"
#include "EventLoop.h"


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

EventLoop* EventLoopThread::startLoop()//开启循环
{
    thread_.start();//启动底层的新线程
	//启动后执行的是EventLoopThread::threadFunc
    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while ( loop_ == nullptr )
        {
            cond_.wait(lock);//挂起,等待  threadFunc中的loop创建好并通知
        }
        loop = loop_;
    }
    return loop;
}

//下面这个方法,start()后的执行的,也就是在单独的新线程里面运行的1
//start()运行后创建新线程,执行绑定的threadFunc函数
void EventLoopThread::threadFunc()
{
    EventLoop loop;//创建一个独立的eventloop,和上面的线程是一一对应的,one loop per thread

    if (callback_)//如果有回调
    {
        callback_(&loop);//绑定loop做一些事情
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;//就是运行在这个线程的loop对象
        cond_.notify_one();//唤醒1个线程
    }

    // 一般来说会一直在loop函数中循环  
    loop.loop();//相当于EventLoop loop  => Poller.poll

    //执行到这个下边就说明服务器程序要关闭掉了
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值