moudo网络库剖析

muduo库介绍 muduo库是一个多线程服务器开发库 muduo 作者陈硕,现在在美国加州硅谷某互联网大公司工作,从事大规模分布式的可靠系统工程。这个库是作者多年工作的总结,可以说大家学通了这个库,找一份Linux服务器开发的工作是没问题的,因为这个库是教大家Linux环境下多线程服务器开发的正规做法,这个库是用的现在C++技术,大量使用了智能指针,bind、function这些技术。 作者还出了一本书《Linux多线程服务端编程:使用muduo C++网络库》,但是这本书不适合初学者,适合具有一定网络编程经验的开发者 阅读详情

muduo简介


muduo是陈硕大神在Linux平台下基于C/C++开发的高性能网络库,在此基础上可以很方便的扩展,进行二次开发编写如http服务器。muduo网络库的核心框架,one thread per thread + Reactor模式。这也是大多数Linux端高性能网络编程框架应用的主要架构。

其本人写的《Linux多线程服务器端编程》对muduo库整个框架和设计细节进行了非常详尽的介绍和分析,非常推荐大家阅读,不仅仅对网络编程有帮助。

此文使用muduo编写了一个简单的echoserver服务器,从用户使用的角度来进行讲解muduo的核心框架、各个组件的交互、优秀的代码设计和实现细节。从源码角度辅助理解整个muduo的实现,希望对网络编程有更深的理解。

从muduo源码中提取出了其核心逻辑,提供一个包含详细注释的muduo库,可以配合源码阅读,删除了定时器事件、大量断言判错、和客户端只保留了muduo库服务端编程的核心框架,代码行数大概2000+,便于剖析其核心。

删减版muduo C++11



阻塞、非阻塞、同步、异步的概念


简单来说,阻塞、非阻塞都是对于操作I/O产生的行为,I/O 无非就是读(read)和写(write)。

以一个sockfd举例,无论是读还是写都有两个阶段,1 等待内核中的接收/发送缓冲区就绪(可读/可写),2 将内核中接收缓冲区数据拷贝至用户区 或 将用户区数据拷贝至发送缓冲区。

linux下默认对sockfd读/写操作,如果未就绪就默认会一直阻塞到就绪事件发生,程序才会继续往下执行,而如果调用了如 fcntl 系统调用对fd设置为了非阻塞,即使数据未就绪也直接返回。


同步与异步


陈硕大神的原话:“在处理 I/O 的时候,阻塞和非阻塞都是同步 I/O。只有使用了特殊的 API 才是异步I/O。”

我的理解是 无论是阻塞I/O、非阻塞I/O、I/O多路复用,都是同步I/O,它们都只是一种就绪事件通知方案,无论是sockfd可读还是可写了,返回的都是就绪事件,用户程序依旧要承担 从用户区将数据拷贝至内核发送缓冲区 或 从内核接收缓冲区将数据拷贝至用户区的时间,而异步I/O通知的是事件完成,用户程序不用承担数据拷贝所花费的时间,拷贝操作已经由内核帮你完成,一返回就可以进行下一步处理。

异步IO相对于同步IO性能更好,但是编程逻辑变得更加复杂,出现了问题也更难排查。



五种IO模型


阻塞IO blocking

在这里插入图片描述

非阻塞IO non-blocking

在这里插入图片描述

IO多路复用(IO multiplexing)

在这里插入图片描述

信号驱动IO(signal-driven)

在这里插入图片描述

异步IO(asynchronous)

在这里插入图片描述



muduo库的框架设计


现代CPU都有许多个核心,服务器这种程序也必须充分利用多核CPU的优势,如何设计多线程服务器?

引用 libevent 网络库作者的观点:one loop per thread is usually a good model

此时问题就转化为了如何设计一个高效的EventLoop,一个线程运行一个EventLoop。

EventLoop是muduo库的核心,muduo库使用的是 IO multiplexing + non-blocking IO + LT模式。

IO多路复用一般和非阻塞IO搭配使用,它们都无法单独使用,不会有人对一个非阻塞的fd一直轮询读取,浪费CPU资源。也不会有人在IO多路复用中使用阻塞IO,读取过程中可能会阻塞当前执行流,导致其余连接迟迟未响应。


muduo的LT模式

Epoll的ET模式通常是高效的代名词,使用ET模式事件就绪只会通知一次,即使一次未将数据读取完毕之后也不再通知,减少了Epoll底层回调机制的触发次数,提高了性能。


ET模式的高效是相对的,为什么muduo使用LT模式?我认为有以下好处:

  1. 低延迟:每次读取/写入只调用一次系统调用,兼顾每个连接,不会因为某个连接需要进行大量读写影响其余连接。
  2. 数据完整性:LT模式只要数据没读完就会一直上报。


Reactor 模型


Reactor模型封装了 对IO的读写、对应事件的回调 、事件操作。

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组件:Event事件、Reactor反应堆、Demultiplex事件分发器、EvantHandler事件处理器



muduo库的Multiple Reactors模型

在这里插入图片描述

图中的每一个Reactor对应一个EventLoop,一个线程运行一个EventLoop,每个Loop上的客户端连接都只能由其所在的Loop进行读写。

以图上一个MianReactor,2个SubReactor 为例:

muduo库中,MianReactor和SubReactor的交互并没有使用简单的同步队列(如生产者消费者模型),而是使用了高效的eventfd系统调用实现通知/唤醒机制,每个Loop都持有一个eventfd句柄,要通知某个Loop只要对其所拥有的eventfd写数据即可。

如果使用了同步队列,在瞬时高并发的场景,此同步队列很可能成为性能瓶颈,同步队列简化了逻辑,使代码更容易实现,但维持同步的性能损耗在高并发场景可能成为性能杀手,而使用eventfd 不涉及任何的 race condttion

性能杀手:锁竞争、上下文切换、数据拷贝、内存申请



muduo库核心组件


Cannel

将已连接的客户端连接 connfd,打包成了一个Cannel,其内部封装了connfd,loop_ (此Channel所在的EventLoop)、event (EPOLLIN/OUT),revent(响应的事件)和对应事件发生时的一系列回调。

muduo库中只有两种channel, 用来监听新连接的 listenfd-acceptorChannel 和客户端的 connChannel ,acceptorChannel 注册在MainLoop的Poller上。


Poller

Poller对应Reactor模型中的事件分发器,向EventLoop返回就绪事件集合,是具体某个IO多路复用的对象,muduo库中的Poller为一个抽象类,muduo提供两个具体的IO多路复用实现,EpollPoller 和 PollPoller 继承Poller类,重写其虚函数,实现其跨平台性,默认使用的是Epoll。



EventLoop

ChannelList activeChannels_;
std::unique_ptr poller_;
int wakeupFd; ->
RPC分布式网络通信框架(二)—— moduo网络解析 moduo网络解析 阅读详情

相关推荐

muduo网络库(1):muduo库整体框架

〇、背景 0.1、本文背景 在学习陈硕《Linux多线程服务端编程:使用muduo C++网络库》muduo源代码的过程中,感觉代码架构较复杂: 一是和boost相关的内容比较多,对现代C++编程理念不了解的人,可能感觉莫名其妙。(关于“现代C++”点击此处) 二是muduo的源代码中,虽然不考虑可移植性,但还是划分了很多小的类(Channel、Socket、TcpConnection、Acce...

李骁睿写技术的地方 976

Linux中Hadoop 集群搭建

零、下载Hadoop: http://archive.cloudera.com/cdh5/cdh/5/?tdsourcetag=s_pctim_aiomsg 一、集群规划: 搭建的 hadoop 集群由 3 台服务器组成,分别叫做 master,salve1 和 slave2。其中 master 作为主节点,slave1 和 slave2 作为从节点。 二、网络配置: 1.查看 3 个节点的主机名...

白墨的小白博客 3991

【头歌educoder】离散数学实训参考-第二章-关系-part1-关系基础

python实现离散数学-关系基础-二元关系

wander_alice的博客 8463

XGBoost的简单安装及入门使用

XGBoost安装及简单入门 XGBoost支持多种操作系统,如Windows, Linux, MacOS等,并支持多种语言版本,如Python, R, Scale, Java等。XGBoost的安装方式一般有两种,一种是直接通过pip安装(适合用于Python),另外一种是通过源码编译安装 1、通过pip安装 通过pip安装Python包既简单又方便,只需执行如下的命令: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xgboost 使用

qq_41513230的博客 3万+

ChatGPT Plus完整开通指南:从账号注册到稳定使用全流程

自然语言处理(NLP)技术通过深度学习模型实现对人类语言的理解与生成,其核心原理是基于Transformer架构的大规模预训练。GPT-4作为当前最先进的生成式AI模型,在代码编写、文档分析等场景展现出显著的技术价值。在实际应用中,稳定的网络环境和合规的支付方式是确保AI助手持续服务的关键因素。针对ChatGPT Plus的开通,需要系统性地解决账号验证、虚拟信用卡支付等工程实践问题,才能实现工作流的高效整合。

weixin_34239592的博客 426

Android流畅度优化实战:从掉帧定位到布局与渲染调优

在移动应用开发中,性能优化是决定用户体验与留存率的关键环节,其中Android流畅度优化更是核心命题。用户感知的“卡顿”往往并非持续低帧率,而是由于掉帧率波动引发的偶发不流畅。本文从性能优化理论出发,系统讲解如何使用Systrace、CPU Profiler等工具定位掉帧瓶颈,深入分析布局层级过深、过度绘制、对象分配与GC压力等常见诱因。同时结合冷启动耗时、列表滚动掉帧、Bitmap加载等真实工程案例,阐述从应用层到系统层的分级优化策略,并给出低端机适配、异步化改造及线上监控体系搭建的实践方案。内容覆盖布局

weixin_29185493的博客 200

SCRFD算法解读及环境安装实践

SCRFD检测算法及环境安装

lishanlu136的博客 1009

第一节:从Chat_Bot 到 AI_Agent——一个范式转换

本文系统剖析了工业级AI代理系统ClaudeCode的设计原理与工程实践。通过对比ChatBot与Agent的三个本质差异:自主循环决策vs单轮应答、环境交互vs纯文本I/O、持久状态管理vs无状态对话,揭示了构建生产级Agent系统的关键挑战。文章详细解析了ClaudeCode的五层架构设计、1800+文件组成的运行时系统,包括工具调度、权限管理、状态持久化等核心机制,并阐述了从简单API调用到完整Agent系统的演进路径。

2201_75869398的博客 67

Ubuntu22.04如何安装cuDNN8.9.7

本文详细介绍了在Ubuntu 22.04系统上为CUDA 12.2安装适配cuDNN 8.9.7的完整流程,特别针对RTX A6000显卡。主要内容包括:1)选择与CUDA 12.2兼容的cuDNN版本;2)使用deb包方式的安装步骤(添加仓库、导入密钥、安装组件);3)通过MNIST示例验证安装;4)版本锁定、卸载旧版等补充说明;5)性能测试方法。文中强调了版本匹配的重要性,并提供了多卡配置建议,为搭建深度学习开发环境提供完整指导。

2501_93651177的博客 1845

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

上一篇: 系统调用 eventfd
下一篇: 音视频基础知识
necesse
博客等级 码龄6年 322粉丝 122原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

necesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值