c++应用网络编程之十一Linux下的epoll模式基础

news2024/10/25 11:25:51

一、epoll模式

在前面分析了select和poll两种IO多路复用的模式,但总体给人的感觉有一种力不从心的感觉。尤其是刚刚接触底层网络开发的程序员,被很多双十一千万并发,游戏百万并发等等已经给唬的一楞一楞的。一听说只支持一两千个并发,便心里感觉这玩意儿是不是在应付人。
这就得多说两句,其实所谓的百万千万并发,并不是说在一台机器上搞的。现在的网络服务端一般都是在云上或者能自己弹性扩容。另外大家需要搞清楚的,很多高并发,看上去非常多,但不是真正的在一秒两秒内完成,它会利用一个缓冲的时间进行最终一致性处理。换句话说,实际的应用工程上,大多在设计上采用一些方法来规避在单机上实现太多的并发。不过反回头来说,不是说单机上不能实现这么高的并发。这需要成本、设计以及开发和网络等的共同努力,并不划算。
需求是技术进步的最重要的推手,正是有上面提到的实际业务需求,才会倒推技术不断的提高并发量。再强的设计,也脱离不开底层网络技术的支持。如果一台单机只支持十个并发,那么如何弹性扩容也就成为了一种灾难的存在。也就是工程创新和技术创新需要协同作战。
高并发的要求,就使的Linux提供了epoll这种新的网络通信模式。可以把epoll当成一个稳定版的select和epoll优化版本,它提供了更强大的并发和更多的数据通信支持。另外,根据实际情况,到底是IO密集型还是CPU密集型或者是二者的混合,epoll提供了水平触发和边缘触发两种方式。不过,在实地看到的版本中,水平触发应用还是比较常见的。但不代表边缘触发用得少。
epoll解决了前面两种模式的两个大问题即文件描述符在用户空间和内核空间的拷贝和描述符控制的限制以及其太多引起的效率的急剧降低。

二、epoll模式的基础

这里要澄清一些问题,就是epoll是不是确实如大家想象的千百倍的提高了网络通信性能。答案可能出乎大家的意料,在一般的应用场景下,可能有很大的提高,但很多场景下,其实epoll未必如此,甚至可能都不如select。大家在网上看到的的连接几十万个甚至上百万个连接的例程,都只是单纯的连接,并没有业务处理或者说极其简单的打印一个类似“Hello”的通信。所以这种例程只是向大家证明,epoll是可以支持上百万个连接的(当然,这需要一系列参数的完善和修改,请参看前面的文章“Socket并发配置之一config的配置”)。
那么怎么判断孰优孰劣呢?还是那句老话,看场景和实际应用环境。比较总是要有限定条件的,不然哪里有什么包打天下的技术。如果单纯从并发的效率来看,如果在小活动连接并发的情况下,epoll几乎是碾压式的胜出select和poll等,看下面的图:
在这里插入图片描述

注意:图中增加了kqueue这种网络模型
这个图需要简单的说明一下,图中是限制了100个活跃连接的基础测试,每个连接进行1000次的读写操作。图中的横轴代表了Socket句柄的数量,纵轴代表了请求响应的时间。从测试结果来看,随着Socket句柄的增加epoll和kqueue几乎不受影响,但Select等两个则有一个明显的上升趋势。
也就是说,在这种场景下,epoll的优势是非常明显的,并且随着Socket句柄的不断的增加性能依然保持稳定,从而更优于Select和Poll。但是,如果活跃的并发是1000个,1万个甚至全都是呢?epoll的优势同样会丧失殆尽。
可实际情况比这种场景可能更复杂,比如客户端同时传输大文件(视频)等,所以实际的类似网络通信会在设计上规避这种响应逻辑或者使用其它的方式(比如类似P2P的方法)。
这种实际的情况告诉开发者,不要迷信技术,要实事求是的综合运用技术来解决问题。
好,从上面的分析,可以明显看出来epoll更适合高并发但瞬时活跃连接并不多的情况下,这种情况比较典型的就是IM及时通信。看上去并发非常多,但同一时间内活跃的并不多,比如一个人聊天,一般也就是和一两个人聊天,而且每次聊天是有间隔的。当然,这并不是说,IM开发简单,恰恰相反,由于其整体并发量的海量存在,使得其更难。或者说,实现一个简单的模型或者框架容易,但真正投入商用需要很长的路。
当然,在边缘触发的情况下,又增加了对大数据量的支持。

三、初步分析

epoll的通信分为边缘触发和水平触发两种情况:
1、水平触发
水平触发,Level Triggered即LT是默认的触发方式,只要在缓冲区内有数据可以读写操作时,epoll_wait则会触发事件,而且只要缓冲区内的数据没有被处理完成一直存在,则会一直触发此事件,直到数据处理完成。这样,就可以保证数据被上层应用准确完整的操作防止出现数据的丢失。但有得就有失,这种连续的触发事件(数据量大时会引起),必然会导致内核态和用户态的切换,降低效率。
特别是EPOLLOUT事件,为了防止连续触发(会产生大量不必要的通知)一定记得删除数据或删除此事件使用时再注册。
2、边缘触发
边缘触发,Edge Triggered即ET也很好理解,就是在发现缓冲区有可操作数据状态变换时,即触发事件,但这种事件只触发一次,直到下一次状态的变化。可能对于有一些硬件经验的开发者更容易理解,当一个电平被拉高时,会有一个上拉的曲线,在这个曲线到达一定位置后(上升沿),状态从0转成1,触发一些动作,然后一直持续到被拉低(下降沿)才会从1变成0.这时才会再次动作。这对于处理一些大数据的传输时很能提高效率,但缺点就是必须自己处理缓存中的所有数据直到确保数据已经操作完成。
注意,这个状态是内核控制的状态而不是用户操作的状态,对于读缓冲,是有新数据到添加到缓冲时触发;对于写缓冲则在是缓冲容量发生变化即内核删除确认的分组使空间空闲此时导致缓冲容易变化。
所以,在边缘触发的情况下,读状态下,必须尽快保证把数据读出,否则下次新增加的数据也不会触发事件(EPOLLIN);写状态下,特别是数据比较大时,数据未发送完成,需要动态的进行写事件(EPOLLOUT)的再次注册。否则无法再次发送。不过正常的情况下,一般对EPOLLOUT的处理比较宽松,只会在异常情况(比如缓冲区溢出)才注册此事件,从而控制再次发送的可能。
在早期的版本中,使用ET的方式,还可以在某些情况下避免惊群的效应。但在新的内核版本中,此种情况已经解决。

在前面Select和Poll的分析中可以知道,其对文件描述符是要进行一个全面的遍历的过程,这就意味着其的复杂度为O(n),而反观epoll则O(1),即其查找的时间是一个恒定的值。
原因就在于,epoll使用的是红黑树+双向链表,它分为为两种情况,一种是传入内核的文件描述符不变,则可以使用上次的结果;另外一种是变化,内核使用红黑树查找并修改双向链表。此时的查询仍然是O(1)。
另外,对于网上很多提及epoll使用了mmap这个事情,目前看源码中并未找到直接调用mmap的代码,可以说epoll并未使用mmap。但epoll确实借鉴了mmap的机制,实现了内核状态与用户状态的事件通知机制。有兴趣可以看一下代码fs/eventpoll.c中的源码。

四、总结

学习epoll可以明显看到技术栈升级的过程。这也再次证明,技术的发展,更多是在前面技术的基础上不断延革的,而技术革命本身就是一种小概率事件。技术革命更类似于基因突变,而正常的技术进步更类似于生物的自然进化。
万物相同,确实如此。

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

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

相关文章

YOLOv9分割改进 ,YOLOv9分割改进主干网络为华为EfficientNet,助力涨点

YOLOv9 分割改进前训练结果: YOLOv9 分割改进后训练结果: 摘要 卷积神经网络(ConvNets)通常在固定的资源预算下开发,然后在有更多资源时进行扩展以提高准确性。在本文中,我们系统地研究了模型扩展,并发现仔细平衡网络深度、宽度和分辨率可以带来更好的性能。基于这一…

【Python库安装】Python环境安装wrf-python库

【Python库安装】Python环境安装wrf-python库 wrf-python库概述Python中安装wrf-python库方式1:使用pip安装方式2:离线安装,使用whl文件安装另:报错 方式3:使用conda安装wrf-python另:报错 参考 wrf-python…

教育培训系统小程序的设计

教师账户功能包括:系统首页,个人中心,课后习题测试管理,观看进度管理,论坛管理,网课信息管理,公告信息管理,学生管理,试卷管理,测试管理 微信端账号功能包括…

RK3568学习之Nginx移植+RTMP推流

1.下载 Nginx 源码 进入到 Ubuntu 系统的某个目录下,下载 Nginx 源码: wget http://nginx.org/download/nginx-1.20.0.tar.gz这里我们下载的是 1.20 版本,这是比较新的版本了。下载完成之后将得到一个名为 nginx-1.20.0.tar.gz的压缩包文件…

嵌入式中数据库sqlit3基本使用方法与现象

大家好,今天主要给大家分享一下,数据库的使用方法,观察对应的效果。 第一:数据库sqlit3基本安装方法 sqlite3 安装 使用 Ubuntu # 安装软件 sudo apt-get install sqlite3# 查看版本 sqlite3 -version# 安装编译工具包 sudo apt-get install sqlite3-dev# 安装可视化工具…

为何2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者?

近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…

html css js 生成随机颜色

起因&#xff0c; 目的: 整理文件&#xff0c;发现之前写的一个小工具。 效果图 点击按钮会生成新的格子。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"wi…

3.计算机网络_端口号

端口号的由来 运输层的作用&#xff1a; 在计算机网络中&#xff0c;运输层处在用户功能的最底层、通信部分的最高层的位置&#xff0c;也就是说运输层是用户数据和实际网络通信的桥梁。因此运输层屏蔽了网络的实现部分&#xff0c;以协议的方式向用户层提供了接口&#xff…

结构体 超详解

目录 1. 结构体的声明与创建 1.1 结构体类型的定义声明&#xff08;类型&#xff09; 1.2 结构体变量的创建和初始化&#xff08;变量&#xff09; 1.3 结构体变量的特殊声明&#xff08;类型和变量&#xff09; 1.3.1 定义时创建变量 1.3.2 结构体的不完全声明&#xff…

SpaceWire原理介绍及FPGA实现

SpaceWire原理及介绍 spacewire特点 SpaceWire 总线具有高速、全双工、点对点、串行传输的特点。它由欧洲航 空局&#xff08;European Space Agency&#xff0c;简称 ESA&#xff09;联合欧洲航空公司等共同发起&#xff0c;由 Dundee 大学制定&#xff0c;以 IEEE-1355 接口…

大数据治理:挑战与实践

目录 大数据治理&#xff1a;挑战与实践 1. 大数据治理的基本概念 2. 大数据治理的关键要素 3. 大数据治理实施框架 3.1 策略与目标制定 3.2 数据治理工具 3.3 数据生命周期管理 4. 大数据治理的挑战与解决方案 5. 大数据治理的价值与未来趋势 5.1 提升决策质量 5.2…

MySQL初识

在了解什么是MySQL前&#xff0c;我们先了解一下什么是数据库&#xff1f;&#xff1f; 1. 数据库简介 1.1 什么是数据库 数据库是20世纪60年代末发展起来的⼀项重要技术&#xff0c;已经成为计算机科学与技术的⼀个重要分⽀。数据库技术主要是⽤来解决数据处理的⾮数值计算问…

【MATLAB代码,带TDOA数据导入】TDOA最小二乘求三维下的位置(1主锚点、3副锚点),多个时间点、输出位置图像

此TDOA&#xff08;Time Difference of Arrival&#xff09;最小二乘法三维定位 MATLAB 工具是一个先进的定位解决方案&#xff0c;专为需要高精度位置计算的工程师、研究人员和开发者设计。此工具可以通过多个时间点的测量数据&#xff0c;结合主锚点和副锚点的配合&#xff0…

Hi3061M——不定长串口接收实现

这里写目录标题 前言串口接收流程串口中断函数ReadITCallBack1中断接收函数 补充结果展示 前言 Hi3061M给了很多相关的串口案例&#xff0c;但大多数是定长的&#xff0c;指定长度进行接收读取&#xff0c;而实际需求往往需要用到不定长的接收。 串口接收流程 首先介绍下Hi3…

Android终端GB28181音视频实时回传设计探讨

技术背景 好多开发者&#xff0c;在调研Android平台GB28181实时回传的时候&#xff0c;对这块整体的流程&#xff0c;没有个整体的了解&#xff0c;本文以大牛直播SDK的SmartGBD设计开发为例&#xff0c;聊下如何在Android终端实现GB28181音视频数据实时回传。 技术实现 Andr…

C++——红黑树(带头结点)

红黑树 红黑树的概念红黑树的定义红黑树的性质红黑树的优点操作原理例图&#xff1a; 红黑树的实现红黑树的框架红黑树的插入实现头结点的作用红黑树的插入步骤&#xff08;简易理解版带图&#xff09; 红黑树的插入具体代码详解红黑树的旋转代码红黑树的查验 红黑树的概念 红…

基于矢量瓦片技术的GIS引擎

矢量地图是通过对点线面坐标信息集合的管理和渲染实现优于栅格画面质量的一种gis展示技术&#xff0c;涉及不同坐标系变换&#xff0c;视窗比例尺换算等。当你遇到海量坐标数据和属性信息需要管理时你就不得不在有限内存和庞大数据间左右为难&#xff0c;将地图矢量数据进行分块…

LabVIEW提高开发效率技巧----时序分析

一、什么是时序分析&#xff1f; 时序分析是优化LabVIEW程序性能的重要步骤。它通过分析程序各个部分的执行时间&#xff0c;帮助开发者找到程序运行中的瓶颈&#xff0c;并进行有针对性的优化。在LabVIEW中&#xff0c;Profile Performance and Memory工具是进行时序分析的关…

浏览器中使用模型

LLM 参数越来越小&#xff0c;使模型跑在端侧成为可能&#xff0c;为什么要模型跑在端侧呢&#xff0c;首先可以节省服务器的算力&#xff0c;现在 GPU 的租用价格还是比较的高的&#xff0c;例如租用一个 A10 的卡1 年都要 3 万多。如果将一部分算力转移到端侧通过小模型进行计…

Linux中真实的调度算法,进程地址空间,命令行参数

文章目录 Linux中真正的调度算法补充 命令行参数什么是命令行参数&#xff1f;命令行参数的用途如何在不同的编程语言中使用命令行参数命令行参数好处 Linux中真正的调度算法 这是Linux2.6的内核中进程队列的数据结构 其中有这两个指针*active,*expired&#xff0c;而Linux为…