当前位置: 首页 > news >正文

muduo - 概要简述

  • 作者:陈硕

  • 编程语言:C++

  • 架构模式:Reactor

  • 代码链接:GitHub - chenshuo/muduo: Event-driven network library for multi-threaded Linux server in C++11

  • 设计自述:https://www.cnblogs.com/Solstice/archive/2010/08/29/muduo_net_lib.html

    • 以下内容,主要援引于自述

设计目标

  • 线程安全,支持多线程

  • 只支持 Linux,不支持 Windows

  • IO multiplexing 使用 poll 和 epoll

  • 主要支持 x86-64,兼顾 IA32

  • 不支持 UDP,只支持 TCP

  • 不支持 IPv6,只支持 IPv4

  • 不考虑广域网应用,只考虑局域网

  • 只支持一种使用模式:non-blocking IO + one event loop per thread,不考虑阻塞 IO

  • API 简单易用,只暴露具体类和标准库里的类,不使用 non-trivial templates,也不使用虚函数

  • 只做 library,不做成 framework

  • 争取全部代码在 5000 行以内(不含测试)

  • 搭配 Google Protocol Buffers RPC

实现简述

Muduo是基于Reactor模式的网络库,其核心是个事件循环EventLoop,用于响应计时器和IO事件。Muduo采用基于对象(object based)而非面向对象(object oriented)的设计风格,其接口多以boost::function + boost::bind表达。

头文件关系

  • 白底:public
  • 黑底:private

接口细节

公开接口

  • Buffer仿 Netty ChannelBuffer 的 buffer class,数据的读写通过 buffer 进行

  • InetAddress封装 IPv4 地址 (end point),注意,muduo 目前不能解析域名,只认 IP

  • EventLoop反应器 Reactor,用户可以注册计时器回调

  • EventLoopThread启动一个线程,在其中运行 EventLoop::loop()

  • TcpConnection整个网络库的核心,封装TCP连接

  • TcpClient用于编写网络客户端,能发起连接,并且有重试功能

  • TcpServer用于编写网络服务器,接受客户的连接

  • 在这些类中,TcpConnection的生命期依靠 shared_ptr 控制(即用户和库共同控制)。Buffer的生命期由TcpConnection控制。其余类的生命期由用户控制。

  • HttpServer 和 Inspector,暴露出一个 http 界面,用于监控进程的状态,类似于 Java JMX。这么做的原因是,《程序员修炼之道》第 6 章第 34 条提到“对于更大、更复杂的服务器代码,提供其操作的内部试图的一种漂亮技术是使用内建的 Web 服务器”,Jeff Dean 也说“(每个 Google 的服务器进程)Export HTML-based status pages for easy diagnosis”。

内部实现

  • Channel是 Selectable IO channel,负责注册与响应 IO 事件,它不拥有 file descriptor。它是 Acceptor、Connector、EventLoop、TimerQueue、TcpConnection 的成员,生命期由后者控制。

  • Socket封装一个 file descriptor,并在析构时关闭 fd。它是 Acceptor、TcpConnection 的成员,生命期由后者控制。EventLoop、TimerQueue 也拥有 fd,但是不封装为 Socket。

  • SocketsOps 封装各种 sockets 系统调用。

  • EventLoop封装事件循环,也是事件分派的中心。它用 eventfd(2) 来异步唤醒,这有别于传统的用一对 pipe(2) 的办法。它用 TimerQueue 作为计时器管理,用 Poller 作为 IO Multiplexing。

  • Poller是 PollPoller 和 EPollPoller 的基类,采用“电平触发”的语意。它是 EventLoop 的成员,生命期由后者控制。

  • PollPollerEPollPoller封装 poll(2) 和 epoll(4) 两种 IO Multiplexing 后端。Poll 的存在价值是便于调试,因为 poll(2) 调用是上下文无关的,用 strace 很容易知道库的行为是否正确。

  • Connector用于发起 TCP 连接,它是 TcpClient 的成员,生命期由后者控制。

  • Acceptor用于接受 TCP 连接,它是 TcpServer 的成员,生命期由后者控制。

  • TimerQueuetimerfd实现定时,这有别于传统的设置 poll/epoll_wait 的等待时长的办法。为了简单起见,目前用链表来管理 Timer,如果有必要可改为优先队列,这样复杂度可从 O(n) 降为 O(ln n) (某些操作甚至是 O(1))。它是EventLoop的成员,生命期由后者控制。

  • EventLoopThreadPool用于创建IO线程池,也就是说把 TcpConnection 分派到一组运行 EventLoop 的线程上。它是 TcpServer 的成员,生命期由后者控制。

线程模型

Muduo的线程模型符合one loop per thread + thread pool模型。

  • 每个线程最多有一个 EventLoop

  • 每个TcpConnection必须归某个EventLoop管理:所有IO操作,所有FDFile Descriptor读写

    • TcpConnection所在的线程由其所属的EventLoop决定

    • TcpConnectionEventLoop是线程安全的,可以跨线程调用

  • TcpServer直接支持多线程,它有两种模式:

    • 单线程,AcceptorTcpConnection用同一个线程做IO。

    • 多线程,AcceptorEventLoop在同一个线程,另外创建一个EventLoopThreadPool,新到的连接会按Round-Robin方式分配到线程池中。

http://www.lryc.cn/news/440395.html

相关文章:

  • Selenium点击元素的方法
  • kali里面搭建docker容器
  • WebGL系列教程八(GLSL着色器基础语法)
  • go多线程
  • 【话题】如何看待IBM中国研发部裁员?
  • 【C/C++】涉及string类的经典OJ编程题
  • 淘系等电商平台API接口系列:商品详情数据解析,json数据返回参考
  • vue组件之间的数据共享
  • LangChain:构建强大的LLM应用的全方位框架
  • 自有平台自有品牌如何利用电商API接口做定价参考(多平台商品详情数据接口)
  • 三万字长文Java面试题——基础篇(注:该篇博客将会一直维护 最新维护时间:2024年9月18日)
  • 数学建模——熵权+TOPSIS+肘部法则+系统聚类
  • Java | Leetcode Java题解之第403题青蛙过河
  • 828华为云征文|华为Flexus云服务器搭建OnlyOffice私有化在线办公套件
  • [Java]maven从入门到进阶
  • Leetcode面试经典150题-130.被围绕的区域
  • Ruffle 继续在开源软件中支持 Adobe Flash Player
  • 【postgres】笔记
  • #if等命令的学习
  • 【有啥问啥】深入浅出马尔可夫链蒙特卡罗(Markov Chain Monte Carlo, MCMC)算法
  • java企业办公自动化OA
  • 【leetcode】树形结构习题
  • 在ros2中安装gazebo遇到报错
  • VMware vSphere 8.0 Update 3b 发布下载,新增功能概览
  • 在设计开发中,如何提高网站的用户体验?
  • 油耳拿什么清理比较好?好用的无线可视挖耳勺推荐
  • 永久配置清华源,告别下载龟速
  • 什么是数据库回表,又该如何避免
  • UE5中使用UTexture2D进行纹理绘制
  • Matlab simulink建模与仿真 第十六章(用户定义函数库)