Muduo类详解之EventLoop

        最核⼼的部分就是 EventLoop 、 Channel 以及 Poller 三个类,其中 EventLoop 可以看作是对业务线程的封装,⽽ Channel 可以看作是对每个已经建⽴连接的封装(即 accept(3) 返回的⽂件描述符)

 EventLoop

class EventLoop {
public:typedef std::function<void()> Function;// 初始化poller, event_fd,给 event_fd 注册到 epoll 中并注册其事件处理回调EventLoop();~EventLoop();// 开始事件循环 调⽤该函数的线程必须是该 EventLoop 所在线程,也就是 Loop 函数不能跨线程调⽤void Loop();// 停⽌ Loopvoid StopLoop();// 如果当前线程就是创建此EventLoop的线程 就调⽤callback(关闭连接 EpollDel) 否则就放⼊等待执⾏
函数区void RunInLoop(Function&& func);// 把此函数放⼊等待执⾏函数区 如果当前是跨线程 或者正在调⽤等待的函数则唤醒void QueueInLoop(Function&& func);// 把fd和绑定的事件注册到epoll内核事件表void PollerAdd(std::shared_ptr<Channel> channel, int timeout = 0);// 在epoll内核事件表修改fd所绑定的事件void PollerMod(std::shared_ptr<Channel> channel, int timeout = 0);// 从epoll内核事件表中删除fd及其绑定的事件void PollerDel(std::shared_ptr<Channel> channel);// 只关闭连接(此时还可以把缓冲区数据写完再关闭)void ShutDown(std::shared_ptr<Channel> channel);
代码随想录知识星球
从 EventLoop 的类定义中可以看出,除了⼀些状态量以外,每个 EventLoop 持有⼀个 Poller 的智能指针(对
epoll / poll 的封装),⼀个⽤于 EventLoop 之间通信的 Channel ,⾃⼰的线程 id,互斥锁以及装有等待处理函
数的 vector 。很明显, EventLoop 并不直接管理各个连接的 Channel (⽂件描述符的封装),⽽是通过
Poller 来进⾏的。 EventLoop 中最核⼼的函数就是 EventLoop::Loop() 。bool is_in_loop_thread();
private:// 创建eventfd 类似管道的 进程间通信⽅式static int CreateEventfd();void HandleRead(); // eventfd的读回调函数(因为event_fd写了数据,所以触发
可读事件,从event_fd读数据)void HandleUpdate(); // eventfd的更新事件回调函数(更新监听事件)void WakeUp(); // 异步唤醒SubLoop的epoll_wait(向event_fd中写⼊数据)void PerformPendingFunctions(); // 执⾏正在等待的函数(SubLoop注册EpollAdd连接套接字以
及绑定事件的函数)
private: std::shared_ptr<Poller> poller_; // io多路复⽤ 分发器int event_fd_; // ⽤于异步唤醒 SubLoop 的 Loop 函数中的
Poll(epoll_wait因为还没有注册fd会⼀直阻塞)std::shared_ptr<Channel> wakeup_channel_; // ⽤于异步唤醒的 channelpid_t thread_id_; // 线程idmutable locker::MutexLock mutex_;std::vector<Function> pending_functions_; // 正在等待处理的函数bool is_stop_; // 是否停⽌事件循环bool is_looping_; // 是否正在事件循环bool is_event_handling_; // 是否正在处理事件bool is_calling_pending_functions_; // 是否正在调⽤等待处理的函数
};
        从 EventLoop 的类定义中可以看出,除了⼀些状态量以外,每个 EventLoop 持有⼀个 Poller 的智能指针(对epoll / poll 的封装),⼀个⽤于 EventLoop 之间通信的 Channel ,⾃⼰的线程 id ,互斥锁以及装有等待处理函数的 vector 。很明显, EventLoop 并不直接管理各个连接的 Channel (⽂件描述符的封装),⽽是通过 Poller 来进⾏的。 EventLoop 中最核⼼的函数就是 EventLoop::Loop()
void EventLoop::Loop() {// 开始事件循环 调⽤该函数的线程必须是该EventLoop所在线程assert(!is_looping_);assert(is_in_loop_thread());is_looping_ = true;is_stop_ = false;while (!is_stop_) {// 1、epoll_wait阻塞 等待就绪事件auto ready_channels = poller_->Poll();is_event_handling_ = true;// 2、处理每个就绪事件(不同channel绑定了不同的callback)for (auto& channel : ready_channels) {channel->HandleEvents();}is_event_handling_ = false;// 3、执⾏正在等待的函数(fd注册到epoll内核事件表)PerformPendingFunctions();// 4、处理超时事件 到期了就从定时器⼩根堆中删除(定时器析构会EpollDel掉fd)poller_->HandleExpire();}is_looping_ = false;
}
        每个 EventLoop 对象都唯⼀绑定了⼀个线程,这个线程其实就在⼀直执⾏这个函数⾥⾯的 while 循环,这个 while 循环的⼤致逻辑⽐较简单。就是调⽤ Poller::poll() 函数获取事件监听器上的监听结果。接下来在 Loop ⾥⾯就会调⽤监听结果中每⼀个 Channel 的处理函数 HandlerEvent() 。每⼀个 Channel 的处理函数会 根据 Channel 中封装的实际发⽣的事件,执⾏ Channel 中封装的各事件处理函数。(⽐如⼀个 Channel 发⽣ 了可读事件,可写事件,则这个 Channel HandlerEvent() 就会调⽤提前注册在这个 Channel 的可读事件 和可写事件处理函数,⼜⽐如另⼀个 Channel 只发⽣了可读事件,那么 HandlerEvent() 就只会调⽤提前注册在这个 Channel 中的可读事件处理函数。
从中可以看到,每个 EventLoop 实际上就做了四件事
1. epoll_wait阻塞 等待就绪事件(没有注册其他fd时,可以通过event_fd来异步唤醒)
2. 处理每个就绪事件
3. 执⾏正在等待的函数(fd注册到epoll内核事件表)
4. 处理超时事件,到期了就从定时器⼩根堆中删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决SLF4J: Class path contains multiple SLF4J bindings.

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 SpringBoot 版本&#xff1a;v2.5.7 maven版本&#xff1a;3.6.3 文章目录 问题描述&#xff1a;原因分析&#xff1a;解决方案&#xff1a;参考资料&#xff1a; 问题描述&#xff1a; 当SpringBoot项目…

并发VS并行

参考文章 面试必考的&#xff1a;并发和并行有什么区别&#xff1f; 并发&#xff1a;一个人同时做多件事&#xff08;射击游戏队友抢装备&#xff09; 并行&#xff1a;多人同时处理同一件事&#xff08;射击游戏敌人同时射击对方&#xff09;

学习数据结构:算法的时间复杂度和空间复杂度

一、算法的复杂度 衡量一个算法的好坏&#xff0c;一般是从时间和空间两个维度来衡量的&#xff0c;即时间复杂度和空间复杂度。 时间复杂度主要衡量一个算法的运行快慢&#xff0c;而空间复杂度主要衡量一个算法运行所需要的额外空间。 算法的时间复杂度 算法中的基本操作的…

SAP BAS中Fiori开发的高阶功能(storyboard, navigation, guided development, variant)

1. 前言 在之前的几篇文章中&#xff0c;我介绍了SAP BAS的一些基本功能&#xff0c;包括账户申请&#xff0c;创建工作区&#xff0c;git的使用以及如何step-by-step去创建出你的第一个Fiori项目等等。在本篇中&#xff0c;我将进一步介绍一些在开发Fiori应用程序时会用到的高…

JAVA学习笔记19(面向对象编程)

1.面向对象编程 1.1 类与对象 1.类与对象的概念 ​ *对象[属性]/[行为] ​ *语法 class cat {String name;int age; }main() {//cat1就是一个对象//创建一只猫Cat cat1 new Cat();//给猫的属性赋值cat1.name "123";cat1.age 10; }​ *类是抽象的&#xff0c;…

前端使用正则表达式进行校验

一、定义 设计思想是用一种描述性的语言定义一个规则&#xff0c;凡是符合规则的字符串&#xff0c;我们就认为它“匹配”了&#xff0c;否则&#xff0c;该字符串就是不合法的。 在 JavaScript中&#xff0c;正则表达式也是对象&#xff0c;构建正则表达式有两种方式&#x…

【可用Claude Opus模型】Claude3国内镜像站,亲测完全超越GPT-4(可用Claude Opus,官网价值20刀)

#今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用Claude 3吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像站到处都是…

探索LLaMA模型:架构创新与Transformer模型的进化之路

引言 在人工智能和自然语言处理领域&#xff0c;预训练语言模型的发展一直在引领着前沿科技的进步。Meta AI&#xff08;前身为Facebook&#xff09;在2023年2月推出的LLaMA&#xff08;Large Language Model Meta AI&#xff09;模型引起了广泛关注。LLaMA模型以其独特的架构…

视频批量爬虫下载工具|可导出视频分享链接|抖音视频提取软件

便捷的视频批量爬虫软件操作指南 抖音视频下载界面图解 主要功能&#xff1a; 关键词批量提取视频和单独视频提取&#xff0c;提取后下载功能。 功能解析&#xff1a; 1. 关键词批量采集视频的解析 对特定关键词进行搜索和视频提取&#xff0c;例如输入“汽车配件”&#x…

2024年洗地机综合实力排行榜:谁才是真正的洗地神器?

近年来&#xff0c;洗地机在行业里&#xff0c;它集合了扫地和拖地以及自动清洁和除菌的功能&#xff0c;备受人们的喜爱&#xff0c;尤其是平时忙于工作并没有多少时间清洁家务的用户&#xff0c;但是对于第一次接触洗地机的用户来说&#xff0c;怎么选购洗地机也是个问题&…

初识React(一)从井字棋游戏开始

写在前面&#xff1a; 磨磨唧唧了好久终于下定决心开始学react&#xff0c;刚刚接触感觉有点无从下脚...新的语法新的格式跟vue就像两种物种...倒是很好奇路由和store是怎么实现的了~v~&#xff0c;一点一点来吧&#xff01;&#xff01;&#xff01; (一)创建项目 使用vite…

蓝桥杯算法 - DP

上一篇&#xff1a;[[蓝桥杯算法-排序、递归、全排列]] 动态规划&#xff08;dp&#xff09; dp即动态规划&#xff0c;常用于&#xff1a;数学&#xff0c;计算机科学&#xff0c;管理学&#xff0c;经济和生物信息学。 dp在生活中也很常见&#xff0c;如&#xff1a;你今天…

今天聊聊Docker

在数字化时代&#xff0c;软件应用的开发和部署变得越来越复杂。环境配置、依赖管理、版本控制等问题给开发者带来了不小的挑战。而Docker作为一种容器化技术&#xff0c;正以其独特的优势成为解决这些问题的利器。本文将介绍Docker的基本概念、优势以及应用场景&#xff0c;帮…

1.4.2 练习

一、颠倒三角形 题目&#xff1a;修改顶点着色器让三角形上下颠倒 更改顶点着色器代码如下&#xff1a; #version 330 corelayout (location 0) in vec3 aPos; //位置变量的属性位置值为0 layout (location 1) in vec3 aColor; //颜色变量的属性位置值为1out vec3 ourColo…

项目配置之道:优化Scrapy参数提升爬虫效率

前言 在当今信息时代&#xff0c;数据是无处不在且无比重要的资源。为了获取有效数据&#xff0c;网络爬虫成为了一项至关重要的技术。Scrapy作为Python中最强大的网络爬虫框架之一&#xff0c;提供了丰富的功能和灵活的操作&#xff0c;让数据采集变得高效而简单。本文将以爬…

线程和进程有什么区别?

1、典型回答 进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统中两个重要的概念&#xff0c;都是用来执行任务的&#xff0c;它们的定义如下&#xff1a; 进程是指计算机中正在运行的程序的实例。每个进程都有自己的地址空间、内存、文件…

生成词云...

import wordcloud import jieba import PIL import numpy as np import matplotlib.pyplot as plt import jieba.analyse image_background PIL.Image.open(/home/back/pythonclass/11.jpg) #遮罩 MASK np.array(image_background) txtopen("/home/back/pythoncla…

如何本地部署Imagewheel并实现无公网IP远程连接打造个人云图床

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

Mysql数据库——数据备份与恢复

目录 一、数据备份的重要性 二、数据库备份的分类 1.从物理与逻辑的角度分类 2.从数据库的备份策略角度&#xff0c;备份可分为 2.1完全备份 2.2差异备份 2.3增量备份 2.4总结 三、常见的备份方法 四、Mysql数据库完全备份 1.完全备份定义 2.优缺点 3.数据库完全备…

2024南京人工智能展会:定于2024年11月份在南京国际博览中心举行

2024南京国际人工智能展览会&#xff0c;拟定于2024年11月份在南京国际博览中心隆重召开。这一盛大的科技盛宴&#xff0c;无疑将为全球人工智能领域注入新的活力&#xff0c;推动科技创新与社会进步。 此次展览会将以“智能未来&#xff0c;共创辉煌”为主题&#xff0c;汇聚全…