【Muduo】网络库框架模型和各模块简介

Muduo是由陈硕大佬个人开发的C++网络库,最近在剖析其源码,在此做一些归纳整理。

框架模型

Muduo网络库的框架模型主要基于Reactor模式,这是一种用于处理多个I/O事件的高效并发模型。

Reactor模式

Reactor模式是一种事件驱动的处理模式,它用于同步地派发基于事件或状态的请求到一个或多个服务处理程序。在Muduo中,Reactor模式被用来处理网络I/O事件,如数据的可读、可写以及错误事件。

核心组件

  • EventLoop:EventLoop是Muduo网络库的核心组件,它负责事件循环的驱动。EventLoop内部维护了一个事件分发器(通常是基于epoll或poll的系统调用),用于监听文件描述符上的事件。当事件发生时,EventLoop会调用相应的事件处理函数。
  • Channel:Channel类封装了一个文件描述符Socket和与之相关的事件处理逻辑。每个Channel对象都注册到EventLoop中,当文件描述符上有事件发生时,EventLoop会通知对应的Channel对象进行处理。
  • Acceptor:Acceptor类负责监听指定的端口,并接受来自客户端的连接请求。当有新的连接请求到达时,Acceptor会创建一个新的TcpConnection对象,并将其与客户端进行关联。同时,Acceptor会将新创建的TcpConnection对象添加到EventLoop的管理列表中。
  • TcpConnection:TcpConnection类代表了一个TCP连接。它封装了与客户端之间的通信逻辑,包括数据的读写、连接的保持和关闭等操作。TcpConnection对象通常是由Acceptor调用TcpServer的回调函数来创建并添加到EventLoop的管理列表中的。

工作流程

  1. 初始化:程序启动时,创建EventLoop对象,并设置监听地址和端口。同时,创建Acceptor对象并将其注册到EventLoop(mainLoop)中。
  2. 监听端口:Acceptor开始监听指定的端口,等待客户端的连接请求。
  3. 接受连接:当有新的连接请求到达时,Acceptor会调用TcpServer的回调函数创建一个新的TcpConnection对象,并将其添加到EventLoop(subLoop)的管理列表中。同时,会设置TcpConnection的相关回调函数(如数据到达时的回调函数)。
  4. 事件循环:EventLoop(subLoop)进入事件循环状态,开始监听文件描述符上的事件。当事件发生时(如TcpConnection上有数据可读),subLoop会调用相应的事件处理函数进行处理。
  5. 数据读写:在事件处理函数中,可以根据事件的类型进行相应的处理。例如,当TcpConnection上有数据可读时,可以从输入缓冲区中读取数据并进行处理;当需要向客户端发送数据时,可以将数据写入输出缓冲区并等待发送机会。
  6. 连接管理:TcpConnection对象负责管理与客户端之间的连接状态。当客户端断开连接时,TcpConnection会从EventLoop的管理列表中移除,并释放相关资源。

各模块简介

Channel模块

内含向Poller中注册的文件描述符fd,封装了感兴趣的事件events、Poller返回的发生的事件revents,和一组能够根据fd发生的事件revents进行回调的回调函数callbacks

共有两种Channel,一种是listenfd - acceptorChannel,一种是connfd - connectionChannel

Poller和EPollPoller  -  Demultiplex

std::unordered_map<int, Channel*> channels_; // key为fd

通过epollctl把Channel中包含的fd注册到epoll上,当epoll返回时,可以通过fd找到Channel,进而进行相应的回调。

EventLoop  -  Reactor

std::vector<Channel *> activeChannels_;std::unique_ptr<Poller> poller_;

一个Eventloop管理一堆Channel和一个poller。Channel想注册到poller上或者在poller上修改自己感兴趣的事件,Channel都是通过EventLoop来获取到poller,进而完成相应任务;同时,poller监听到sockfd有相应事件发生,也要通过EventLoop来调用相应Channel的fd的所发生事件的回调函数。 

int wakeupFd_;  // 一个wakeupfd隶属于一个loopstd::unique_ptr<Channel> wakeupChannel_;

loop执行的时候,驱动底层的事件分发器Demultiplx也即epoll_wait,若没有事件发送,则loop一定阻塞在epoll_wait上;若是想唤醒某个loop的阻塞状态,那就可以通过loop对象获取其对应的wakeupfd,并往wakeupfd写一点数据,来使loop从epoll_wait上返回,这是因为每一个wakeupfd也封装成了一个wakeupChannel,注册在了底层的epoll上。

std::vector<Functor> pendingFunctors_;

如果当前线程要调用其他线程中的loop进行回调操作,则将回调函数存放到pendingFunctors_中,并weakup相应的loop。

Thread、EventLoopThread和EventLoopThreadPool

EventLoop *getNextLoop(); 

通过轮询算法获取下一个subLoop,如果没有setThreadNum设置多线程,那么获取到的永远是baseLoop;如果有设置过多线程,那么threadPool会驱动底层创建新线程,一个thread对应一个loop,即 one loop per thread 

Socket、Acceptor

主要封装了listenfd相关操作,socket创建、bind、listen,listen开启后打包成acceptorChannel,放到baseLoop去执行 

Buffer

缓冲区  应用写数据 =》缓冲区 =》 Tcp发送缓冲区 =》 send

+-------------------+------------------+------------------+
| prependable bytes |  readable bytes  |  writable bytes  |
|      缓冲区头     |     (CONTENT)    |     可写空间     |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=     size

TcpConnection

一个连接成功的客户端对应一个TcpConnection,封装了SocketChannel和各种回调函数,还有发送和接收缓冲区

TcpServer

封装AcceptorEventLoopThreadPool,以及

std::unordered_map<std::string, TcpConnectionPtr> connections_;

接下来将在专栏更新各模块的具体重新实现

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

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

相关文章

Java 面向数据编程-DOP

近年来&#xff0c;Java 获得了许多新的语言特性&#xff0c;这些特性可以独立使用&#xff0c;并且每个特性都很有用&#xff1a;类型模式&#xff08;type patterns&#xff09;、开关改进&#xff08;switch improvements&#xff09;、记录和记录模式&#xff08; records …

纯正英语新闻 5.26

brutal&#xff1a;残暴的 apartheid&#xff1a;隔离 discrimination&#xff1a;歧视 segregation&#xff1a;隔离 humiliation&#xff1a;屈辱 unfolding&#xff1a;展开 shuffle forward&#xff1a;向前推进 justice&#xff1a;正义 endure&#xff1a;经久不…

分享几张漂亮的linux kde主题

分享几张漂亮的linux kde主题&#xff1a;在系统设置的全局主题内下载。

开源大模型与闭源大模型

概述 开源大模型和闭源大模型是两种常见的大模型类型&#xff0c;它们在以下方面存在差异&#xff1a; 开放性&#xff1a; 开源大模型&#xff1a;代码和模型结构是公开可用的&#xff0c;任何人都可以访问、修改和使用。闭源大模型&#xff1a;模型的代码和结构是私有的&…

求斐波那契数列第n项的值

本期介绍&#x1f356; 主要介绍&#xff1a;什么是斐波那契数列&#xff0c;递归实现求斐波那契数列第n项值&#xff0c;递归法为什么不适合求斐波那契数&#xff0c;用迭代法实现求斐波那契数列的值&#x1f440;。 文章目录 1. 斐波那契数列是什么&#xff1f;2. 题目2. 递归…

iOS17闪退问题 *** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloa

ios升级17以后运行闪退。报错日志为*** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410 根据相关断点跟踪&#xff0c;具体报错位置 查看相关api发现iOS17api已经被替代。 替代方式为将UIGraphicsBegin…

9.Docker网络

文章目录 1、Docker网络简介2、常用基本命令3、网络模式对比举例3.1、bridge模式3.2、host模式3.3、none模式3.4、container模式3.5、自定义网络 1、Docker网络简介 作用&#xff1a; 容器间的互联和通信以及端口映射容器IP变动时候可以通过服务名直接进行网络通信而不受到影…

# 文件或目录损坏且无法读取 的解决方案

文件或目录损坏且无法读取 的解决方案 一、问题描述&#xff1a; windows 系统下&#xff0c;当对某一个文件或文件夹操作时&#xff0c;出现【文件或目录损坏且无法读取】&#xff0c;这时不管对其进行修改、删除、更改属性等操作&#xff0c;都不能正常进行&#xff0c;在 …

从0开始学统计-t检验

1.什么是t检验&#xff1f; t检验是一种用于比较两个样本均值之间差异是否显著的统计方法。它通常用于以下几种情况&#xff1a; &#xff08;1&#xff09;单样本 t 检验&#xff1a;用于检验一个样本的平均值是否与一个已知的总体平均值&#xff08;或者一个假设的总体平均…

手把手教你如何使用BurpSuite

Burp Suite是什么&#xff1f; 概述 Burp Suite是由PortSwigger公司开发的一款综合性Web应用安全测试工具。它是安全研究人员和渗透测试人员的标准工具&#xff0c;用于识别和利用Web应用程序中的漏洞。Burp Suite提供了一系列强大的功能&#xff0c;帮助用户对Web应用进行全…

手写Zookeeper分布式锁

zookeeper版本&#xff1a;zookeeper-3.4.13&#xff0c;该版本原生api不支持递归创建节点 依赖 <dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.13</version> </depende…

深入理解Nginx try_files:用途、使用场景、注意事项和示例

Nginx 是高性能的 HTTP 和反向代理服务器&#xff0c;而 try_files 是其功能强大的模块之一。try_files 指令用于定义一组文件或 URI&#xff0c;Nginx 将依次检查这些文件或 URI&#xff0c;直到找到一个存在并可访问的文件或 URI。本文将深度解析 try_files 的用途、使用场景…

11.jenkins调整上线的脚本实现tag方式上线

jenkins调整上线的脚本实现tag方式上线 多次打标签重新提交到gitlab远程仓库-基于multi-line string parameter 修改脚本html_deploy_tar.sh #!/usr/bin/bashDate$(date %F-%H-%M) web_server"192.168.111.22 192.168.111.23" Name${Date}-${git_version} code_t…

网络模型-路由策略

一、路由策略 路由策略(Routing Policy)作用于路由&#xff0c;主要实现了路由过滤和路由属性设置等功能&#xff0c;它通过改变路由属性(包括可达性)来改变网络流量所经过的路径。目的:设备在发布、接收和引入路由信息时&#xff0c;根据实际组网需要实施一些策略&#xff0c…

Spring Boot 3.3新特性发布

Spring Boot 3.3 现已正式发布&#xff01;此版本包含大量更新&#xff0c;包括多项新功能。我们决定进行一些挑选&#xff0c;并查看最重要的变化&#xff0c;其中包括对类数据共享 (CDS) 的支持&#xff0c;以加快应用程序启动速度。 1.新的服务连接 Spring Boot 中改进或添…

MathType安装以及要点和难点

MathType是一款专业的数学公式编辑器,主要用于在文档中输入复杂的数学、物理公式和符号。以下是关于MathType的一些主要特点和功能: 1.定义设置:在MathType的“样式-定义”中,可以对数学、文本、函数、变量等不同类型进行定义。定义好之后,后续在公式编辑的时候,可以根据…

笔记89:LeetCode_135_分发糖果

前言&#xff1a; 注&#xff1a;代码随想录中没有很清楚的提起想出方法的思路&#xff0c;只是给出了解决这个问题的大致思路和代码&#xff1b;下面我将介绍一下我的思考过程&#xff0c;并贴出实现代码&#xff1b; a a a a 思考过程&#xff1a; 思路1&#xff1a;为了…

【实际项目精选源码】ehr人力资源管理系统实现案例(java,vue)

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化人力资源管理系统&#xff0c;涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块&#xff0c;解决了从人事招聘到酬薪计算的全周期人力资源管理&#xff0c;符合当下大中小型企业组织架构管理运…

Gateway配置教程

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;它基于 Spring 5.0、Spring Boot 2.x 和 Project Reactor 等技术开发的网关&#xff0c;旨在提供一种简单、有效、统一的 API 路由管理方式。以下是 Spring Cloud Gateway 的基本配置步骤&#xff1a; 1. 添加…

Spring Boot 如何使用 AOP 防止重复提交

在 Spring Boot 中&#xff0c;可以使用 AOP&#xff08;面向切面编程&#xff09;来防止重复提交。通过 AOP&#xff0c;可以在方法调用前后添加额外的逻辑&#xff0c;而不需要修改方法本身的代码。下面是一个基于 AOP 的解决方案&#xff1a; 使用 AOP 防止重复提交 步骤&…