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

2024-05-16 15:52

本文主要是介绍[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.pollstd::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类 ~ 我们下一节见 ~~

这篇关于[muduo网络库]——muduo库EventLoopThread类(剖析muduo网络库核心部分、设计思想)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995349

相关文章

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解