muduo 架构解析

2023-11-17

    muduo是一个基于Reactor模式的C++网络库。它采用非阻塞I/O模型,基于事件驱动和回调。我们不仅可以通过muduo来学习linux服务端多线程编程,还可以通过它来学习C++11。
    Reactor是网络编程的一般范式。我们这里从reactor模式为出发点,根据Reactor模式的特点剖析muduo的架构设计。根据wiki的定义:

The reactor design pattern is an event handling pattern for handling
service requests delivered concurrently to a service handler by one or
more inputs. The service handler then demultiplexes the incoming
requests and dispatches them synchronously to the associated request
handlers.

    我们可以知道,Reactor模式的基础是事件驱动,事件源可以有多个,并且会并发地产生事件。Reactor模式的核心是一个事件分发器和多个事件处理器,多个事件源向事件分发器发送事件,并要求事件分发器响应,reactor模式的设计难点也是在事件分发器,它必须能够有条不紊地把响应时间分派到合适的事件处理器中,保证事件处理的最小延迟。事件处理器主要是负责处理事件的业务逻辑,这是关系到具体事件的核心,因此和事件分发器不一样,它并不太具有一般性。

这里写图片描述

    Reactor模式的特点可以很自然地应用到C/S架构中。在C/S架构的应用程序中,多个客户端会同时向服务端发送request请求。服务端接收请求,并根据请求内容处理请求,最后向客户端发送请求结果。这里,客户端就相当于事件源,服务端由事件分发器和事件处理器组成。分发器的任务主要是解析请求和将解析后的请求发送到具体的事件处理器中。

从Reactor模式到C/S架构

    从技术的层面来说,怎么把“事件”这个概念放到“请求”上,也就是怎么样使得请求到来可以触发事件,是一个难点。从设计的层面上来说,怎么样分发事件使得响应延迟最小,并保持高可扩展性是难点(架构能够较好地适应各种事件的处理和事件数量的变化)。对于技术层面,linux上的解决方案是:epoll,select等。而设计层面,muduo提供了较好的解决方案。
    Muduo的基础设施是epoll,并在此基础上实现了one-thread-one-loop和thread-pool设计方案。也就是将事件处理器设置成线程池,每个线程对应一个事件处理器;因为事件处理器主要处理的是I/O事件,而且每个事件处理器可能会处理一个连接上的多个I/O事件,而不是处理完一个事件后直接断开,因此muduo选择每个事件处理器一个event-loop。这样,连接建立后,对于这条连接上的所有事件全权由它的事件处理器在event-loop中处理。
    我们可以根据上面的reactor架构图,简单地绘制出muduo的架构图:

muduo架构图

    如图所示,客户端首先和服务端建立连接,如图橙色线所示。建立连接之后将这个连接分发到具体的Eventloopthread中(所有的eventloopthread由server中的一个eventloopthreadpool线程池管理),这部分主要由server中的Acceptor完成。后续client就不再和Acceptor发生关系了。因此可以看出,建立连接之后,client直接和Eventloopthread关联,不再经过Acceptor。
    由于连接本身也是一个事件,因此Acceptor的工作是等待事件和分发事件,因此它也是在一个eventloop中。
    下面我们看一下Tcpserver类成员,其实类中的*loop_指向的其实就是Acceptor所在的eventloop。因此Acceptor的eventloop并不是存在于eventloopthreadpool中的。不过后面我们会看到,这个eventloop结构也是会传入到eventloopthreadpool结构中,由eventloopthreadpool的baseloop标识,这主要是为了管理server中的所有eventloop方便。

这里写图片描述

    至此我们便介绍完了muduo中的Tcpserver架构。后面我们将从此展开,深入到具体细节中。比如怎么管理eventloopthread,建立好的连接怎么放入到eventloopthread中,以及eventloopthread怎么管理和客户端直接的I/O连接,eventloop怎么管理各个事件的处理逻辑等等。最后我们还将介绍muduo实现的一些架构之外的技术细节,比如缓冲区管理,日志系统,定时器管理等等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

muduo 架构解析 的相关文章

  • 在 fread(3) 中检查读取的项目数是否小于请求的数量,而不是 0,是否正确?

    我是 C 的初学者 我想知道检查返回值是否正确fread 3 即读取的项目数 小于检测 EOF 所请求的数量 而不仅仅是 0 例如 假设你有 include
  • 如何测试是否支持稀疏文件

    给定文件描述符或文件名 我如何知道是否可以写入任意位置 而无需等待磁盘上的中间部分被显式清零 You can stat 文件获取文件大小和磁盘块数量 在文件末尾查找相对较少数量的磁盘块 写入已知数量的块 然后再次统计文件 将磁盘块的原始数量
  • 如何从函数中实时捕获打印内容?

    我想捕捉所有prints 并执行诸如返回它们之类的操作 但继续运行该函数 我找到了这个方法 但它只返回print代码完成后 f io StringIO with redirect stdout f my code return f getv
  • C++ 使用不同的流读取和写入同一文件

    我有两个流指向同一个文件 第一个是std ofstream os第二个是std ifstream is 都以二进制模式打开 我在用着os创建一个新文件 文件创建过程需要我 有时 读取写入文件的数据os The is流寻找所需的位置 读取一些
  • 接受用户输入

    我目前正在 Malbolge 中编写一款文字冒险类型游戏 谁能告诉我如何在 Malbolge 中接受用户输入 我能够将文本输出到屏幕上 但是 我似乎不知道如何接受输入 GHJUYGHJKLKUJHM MJ 6AG9F5D8V A8 gt 7
  • PrintWriter 未打印出完整的字符串

    我有以下代码 FileWriter F new FileWriter out txt PrintWriter H new PrintWriter F H print split split length 2 H print END 然而 当
  • 使用 x64 汇编代码的基本输入

    我正在编写有关汇编中基本输入和输出的教程 我使用的是 64 位 Linux 发行版 Ubuntu 在教程的第一部分中 我讨论了基本输出并创建了一个简单的程序 如下所示 global start section text start mov
  • 有FlushFileBuffers和FILE_FLAG_NO_BUFFFERING不同用途的比较或者性能表吗?

    我将选择在每次写入文件后使用 FlushFileBuffers 或每次需要打开同一个文件时使用 FILE FLAG NO BUFFFERING 但我没有找到任何关于使用一个或另一个选项的性能比较表 好吧 除了这个建议in MSDN http
  • 使用 System.IO.File 辅助方法的“顺序”文件 I/O 安全吗?

    我刚刚看到这个问题 在 C 中的 File 类上使用静态方法安全吗 https stackoverflow com q 32413634 1207195 总结一下OP有一个IOException因为该 ASP NET 代码片段中正在使用文件
  • 如何在 Perl 6 中追加到文件?

    我正在尝试这个和其他一些事情 但它每次都会截断文件 my file primes txt sub MAIN Int D low Int D high where gt low unless my fh open file w append
  • BufferedReader会将整个文件加载到内存中吗?

    class LogReader public void readLogFile String path BufferedReader br new BufferedReader new FileReader path String curr
  • 如何使用 Spring 注入键值属性文件?

    我有一个键值属性文件 其中包含错误代码及其错误消息 我想在应用程序启动时注入此文件 以便我可以在注入的属性上进行查找 而无需读取该文件 下面只是伪代码 里面有什么吗Spring可以创建这个设置吗 Value location classpa
  • 有没有更好的方法将文件的完整内容写入 OutputStream?

    当我想将文件的全部内容写入OutputStream 我通常分配一个缓冲区作为byte 然后做一个for循环到read来自文件的数据InputStream写入缓冲区并将缓冲区内容写入OutputStream 直到InputStream没有更多
  • 将二进制文件读入结构体

    我正在尝试使用 C 读取二进制数据 我拥有有关我想要读取的文件中的数据布局的所有信息 我能够 逐块 读取数据 即将前 40 个字节的数据转换为字符串 然后获取接下来的 40 个字节 由于数据至少有三个略有不同的版本 我想将数据直接读入结构中
  • 没有 fflush(stdout) 则输出不打印

    我不明白为什么有时我需要使用fflush 有时不是 我的程序目前出现段错误 我正在使用 print 语句对其进行调试 当程序出现段错误时 stdout不自动刷新缓冲区 我不明白为什么有时需要使用 fflush 而有时需要使用 不是 有时 s
  • 关闭/清理“混合”文件描述符/套接字

    当我使用accept 创建一个套接字并使用fdopen 从中创建一个文件时 我需要做什么来清理所有内容 我是否需要对 FILE 执行 fclose 对套接字执行 shutdown 和 close 还是只需要 shutdown 和 或 clo
  • 读取 CSV 文件单列的更快方法

    我正在尝试阅读一个列CSV文件至R尽快 我希望将标准方法将列放入 RAM 所需的时间减少 10 倍 我的动机是什么 我有两个文件 一个叫Main csv这是 300000 行和 500 列 其中一个称为Second csv即 300000
  • 在Python中修改大型文本文件最后一行的最有效方法

    我需要更新几个超过 2GB 的文件的最后一行 这些文件由无法读取的文本行组成readlines 目前 它可以通过逐行循环来正常工作 但是 我想知道是否有任何编译库可以更有效地实现这一点 谢谢 目前的方法 myfile open large
  • java中filewriter的flush和close函数之间的区别

    我需要知道Java中的flush和close函数之间的确切区别是什么 当在写入文件期间将数据转储到文件中时 请提供一个例子 flush just确保所有缓冲数据都写入磁盘 在这种情况下 更一般地说 通过您正在使用的任何 IO 通道刷新 之后
  • 如何通过pthreads管理两个或多个消费者?

    我有一个正在寻求解决的通用问题 即从标准输入或常规文件流发送到应用程序的二进制数据块 应用程序又将二进制数据转换为文本 使用线程 我想在将文本传输到下一个应用程序之前对其进行处理 该应用程序会进一步修改该文本 依此类推 作为一个简单的测试用

随机推荐

  • websocket菜鸟教程(1.1)

    创建自己的websocket服务 先了解node js websocket 的基本使用https www npmjs com package nodejs websocket 第一步先安装 npm install nodejs websoc
  • mysql5.6安装步骤详细_详解MySQL5.6安装步骤

    是开放源码的小型关系型数据库管理系统 目前MySQL被广泛应用于在Internet上的中小型网站中 但是对于刚接触MySQL数据库服务器的朋友来说 是非常陌生的 那么现在爱站小编为大家详解MySQL5 6步骤 1 点击下载好的安装文件 出现
  • console控制台错误及处理过程

    1 ERROR Failed to execute goal org apache maven plugins maven compiler plugin 2 5 1 compile default compile on project l
  • 为什么组件中的data是一个函数而不是一个对象?

    JS中的对象是引用类型的数据 当多个实例引用同一个对象时 只要有一个实例对这个对象进行操作 其他实例中的数据也会发生变化 而在vue中 更想要每个组件都有自己的数据 不会互相干扰 所以组件的数据不能写成对象的形式而要是函数的形式 数据以函数
  • Ubuntu下非常给力的下载工具

    Windows下的下载工具 迅雷 之所以下载速度快 乃是它能搜索资源 为己所用 而不是仅仅从原始地址这单一资源处下载 Ubuntu下也有类似的工具 那就是aira2 aira2是一个命令行下载工具 可以配合其他图形界面的下载软件使用 我用的
  • HyperLogLog数据结构

    基数计数 cardinality counting 通常用来统计一个集合中不重复的元素个数 例如统计某个网站的UV 或者用户搜索网站的关键词数量 数据分析 网络监控及数据库优化等领域都会涉及到基数计数的需求 要实现基数计数 最简单的做法是记
  • python读取csmar_如何优雅的把CSMAR(国泰安)数据导入R

    前言CSMAR 国泰安 数据库是经济金融相关的科研工作者用到的最多的数据库之一 它提供了丰富全面的上市公司财务及金融数据 以及一些行业宏观层面的数据 但是 它并没有像WRDS 沃顿研究数据服务 等数据库提供丰富接口 如SAS R等 供下载
  • 论文阅读笔记之——《Multi-level Wavelet-CNN for Image Restoration》及基于pytorch的复现

    本博文是MWCNN的阅读笔记 论文的链接 https arxiv org pdf 1805 07071 pdf 代码 https github com lpj0 MWCNN 仅仅是matlab代码 通过参考代码 对该网络在pytorch框架
  • C语言库函数——快排函数qsort()

    目录 一 函数原型 二 函数介绍 三 函数使用 常见写法 比较函数 四 函数实例 1 int型数组 2 double型数组 3 char型数组 4 字符串 5 结构体 一级结构 二级结构 一 函数原型 void qsort void bas
  • CAN协议详解-01

    CAN 是控制器局域网络 Controller Area Network 的简称 它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的 并最终成为国际标准 ISO11519以及ISO11898 是国际上应用最广泛的现场总线之一 差
  • 《机器学习实战》第14章学习笔记(数据约简工具---SVD)

    一 SVD基本原理 提取这些信息的方法称为奇异值分解 Singular Value Decomposition SVD 在很多情况下 数据中的一小段携带了数据集中的大部分信息 其他信息则要么是噪声 要么就是毫不相关的信息 在线性代数中还有很
  • unity如何解决每次写完敲代码,调试时需要卡个进度条

    解决办法如下 勾选上之后程序就可以立刻运行起来了 再也不用一直卡进度条了 不过也有弊端的 会影响静态字段初始化有问题还有Dotween的一些效果会发生变化 谨慎避免入坑
  • armbian安装图形桌面_Linux的图形用户界面-你会选择哪个?

    时至今日 Linux在服务器端的地位是毋庸置疑的 其常见的命令行界面是相当稳定的 图形界面嘛 存在众多版本 兼容性有待进一步提升 常见的图形界面有 以ubuntu系统为例 Unity 这是Ubuntu自带的图形界面 相当炫 但吃内存比较大
  • 毕业设计-基于机器学习的中文文本分类算法

    目录 前言 课题背景和意义 实现技术思路 一 文本分类综述 二 文本分类相关技术简 1 文本处理过程 2 分类算法 3 分类算法评价方法 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学
  • Snowy Smile【扫描线】【2019 杭电多校6】

    HDU 6638 题目链接 比赛的时候只在拼命的想怎么去优化O N 3 的那个之前所认为的标准解法 没想到 这就是一道O N 2 logN 的扫描线 我们可以固定上下两个区间 然后在固定的区域中 就是一维的空间了 我们直接在这一维里去查询即
  • 数字芯片流程

    芯片设计分为前端设计和后端设计 前端设计 逻辑设计 和后端设计 物理设计 并没有同意严格的界限 这个过程中涉及到了与工艺有关的设计就是后端设计 一 需求分析 产品需要解决的问题 预测3 5年的趋向和走势 确保前瞻性 确保芯片是有卖点的 客户
  • kong dashboard UI 的使用 (使用kong 对服务反向代理,以及解决跨域问题)

    7 2Choose Security and click on ADD PLUGIN in cors then don t input content and click on ADD PLUGIN button directly 第一步登
  • 【Zotero6】插件Zotcard自定义笔记模板流程分享

    Zotero 个人感觉比Endnote更好用的文献管理器 集翻译 文献整理 笔记 查询期刊影响因子 期刊分区等集于一身的文献管理器 据说是一款开源软件官网就可以免费下载 安装附加的浏览器插件使用更方便 今天更新的是Zotero中的笔记插件
  • 计算机操作系统pcb是什么意思,简述PCB的含义以及作用

    描述 为了使参与并发执行的每个程序 包含数据都能独立地运行 在操作系统中必须为之配置一个专门的数据结构 称为进程控制块 PCB Process Control Block 进程与PCB是一一对应的 用户进程不能修改 进程控制块PCB的作用
  • muduo 架构解析

    muduo是一个基于Reactor模式的C 网络库 它采用非阻塞I O模型 基于事件驱动和回调 我们不仅可以通过muduo来学习linux服务端多线程编程 还可以通过它来学习C 11 Reactor是网络编程的一般范式 我们这里从react