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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】Linux进程地址空间

1.程序地址空间分配回顾 在前⾯C语⾔以及C部分介绍过⼆者的内存分配如下图所示: 全局变量区和未初始化全局变量区也被称为数据区,数据区中除了有全局变 量,还有静态变量和常量 使⽤下⾯的代码演示不同的内容所处的地址: #includ…

Element-ui官方示例(Popover 弹出框)

Element-ui官方示例(Popover 弹出框),好用的弹出框。 使用 vue-cli3 我们为新版的 vue-cli 准备了相应的​Element 插件​,你可以用它们快速地搭建一个基于 Element 的项目。 使用 Starter Kit 我们提供了通用的项目模版&#…

深入探讨C++多线程性能优化

深入探讨C多线程性能优化 在现代软件开发中,多线程编程已成为提升应用程序性能和响应速度的关键技术之一。尤其在C领域,多线程编程不仅能充分利用多核处理器的优势,还能显著提高计算密集型任务的效率。然而,多线程编程也带来了诸…

Redis应用高频面试题

Redis 作为一个高性能的分布式缓存系统,广泛应用于后端开发中,因此在后端研发面试中,关于 Redis 的问题十分常见。 本文整理了30个常见的 Redis 面试题目,涵盖了 Redis 的源码、数据结构、原理、集群模式等方面的知识,并附上简要的回答,帮助大家更好地准备相关的面试。 …

【Windows】【DevOps】Windows Server 2022 采用WinSW将一个控制台应用程序作为服务启动(方便)

下载WinSW 项目地址: GitHub - winsw/winsw: A wrapper executable that can run any executable as a Windows service, in a permissive license. 下载地址: https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe 参考配置模…

深度学习 之 模型部署 使用Flask和PyTorch构建图像分类Web服务

引言 随着深度学习的发展,图像分类已成为一项基础的技术,被广泛应用于各种场景之中。本文将介绍如何使用Flask框架和PyTorch库来构建一个简单的图像分类Web服务。通过这个服务,用户可以通过HTTP POST请求上传花朵图片,然后由后端…

Nginx(Linux):服务器版本升级和新增模块

目录 1、概述2、使用Nginx服务信号完成Nginx升级2.1 备份当前版本的Nginx2.2 向服务器导入新的Nginx2.3 向服务器导入新的Nginx2.4 停止老版本Nginx 3、使用Nginx安装目录的make命令完成升级3.1 备份当前版本的Nginx3.2 向服务器导入新的Nginx3.3 执行更新命令 1、概述 如果想…

E41.【C语言】练习:斐波那契函数的空间复杂度的计算及函数调用分析

目录 1.题目 2.解 Fib嵌套函数调用细则的分析 调用堆栈分析 之后的具体内容见视频 附:一张核心图 附:一张堆栈图 注意 1.题目 求下列代码的时间复杂度 long long f(size_t n) {if(n < 3)return 1;return f(n-1) f(n-2); } 2.解 显然是递归算法(递归讲解见35.【…

推荐一款多显示器管理工具:DisplayMagician

DisplayMagician是一款开源工具&#xff0c;专为Windows用户设计&#xff0c;能够通过一个快捷方式轻松自动配置屏幕和声音。它特别适合游戏玩家和应用程序用户&#xff0c;可以实现屏幕配置、声音设备切换以及启动额外程序等功能&#xff0c;最后在游戏或应用程序关闭时&#…

实现vlan间的通信

方法一&#xff1a;单臂路由 概述 单臂路由是一种网络配置&#xff0c;它允许在路由器的一个物理接口上通过配置多个子接口来处理不同VLAN的流量&#xff0c;从而实现VLAN间的通信。 原理 路由器重新封装MAC地址&#xff0c;转换Vlan标签 基础模型 1、配置交换机的链…

Vxe UI vue vxe-table grid 如何滚动、定位到指定行或列

Vxe UI vue vxe-table vxe-grid 在表格中有时候需要对数据会列进行操作。可以会定位到某一行或某一列&#xff0c;vxe-table 中提供了丰富的函数式 API&#xff0c;可以轻松对行与列进行各种的灵活的操作。 定位到指定行与列 通过调用 scrollColumn(columnOrField) 方法&…

阿里云云盘在卸载时关联到PHP进程,如何在不影响PHP进程情况下卸载磁盘

1.问题&#xff1a; 在使用umount /dev/vdc1 卸载磁盘时&#xff0c;提示如下&#xff0c;导致无法在Linux系统下卸载磁盘 umount /dev/vdc1 umount: /var/www/html/*/eshop/IFile3: target is busy.(In some cases useful info about processes that usethe device is found…

WPF -- LiveCharts的使用和源码

LiveCharts 是一个开源的 .NET 图表库&#xff0c;特别适用于 WPF、WinForms 和其他 .NET 平台。它提供了丰富的图表类型和功能&#xff0c;使开发者能够轻松地在应用程序中创建动态和交互式图表。下面我将使用WPF平台创建一个测试实例。 一、LiveCharts的安装和使用 1.安装N…

网盘直链下载神器NDM

工具介绍 ​Neat Download Manager分享一款网盘不限速神器,安装步骤稍微有一点繁琐,但实际体验下载速度飞快,个人实际体验还是非常不错的 NDM是一款免费且强大的下载工具。可以帮助你下载各种文件&#xff0c;还能够在多任务下载中保持出色的速度及其稳定性 通过网盘分享的文…

五年三次冲刺IPO失败,企业业绩成长性恐不足,三年分红约1.5亿元

中超股份终止原因如下&#xff1a;首先&#xff0c;报告期&#xff0c;中超股份营收和净利润增幅出现下降趋势&#xff0c;公司业绩规模成长性恐不足。其次&#xff0c;公司货币资金较为紧张情况下&#xff0c;仍在报告期内连续三年分红&#xff0c;累计1.46亿元&#xff0c;募…

Java爬虫:获取直播带货数据的实战指南

在当今数字化时代&#xff0c;直播带货已成为电商领域的新热点&#xff0c;通过直播平台展示商品并进行销售&#xff0c;有效促进了产品的曝光和销售量的提升。然而&#xff0c;如何在直播带货过程中进行数据分析和评估效果&#xff0c;成为了摆在商家面前的一个重要问题。本文…

边缘计算技术的优势与挑战

如今&#xff0c;随着5G快速无线网络的到来&#xff0c;将计算存储和物联网&#xff08;IoT&#xff09;分析的部署放在靠近数据产生的地方&#xff0c;使得边缘计算成为可能。 物联网设备和新应用的扩展需要实时计算能力。5G无线正在考虑边缘系统&#xff0c;以快速跟踪支持实…

016集——c# 实现CAD类库 与窗体的交互(CAD—C#二次开发入门)

第一步&#xff1a;搭建CAD类库dll开发环境。 第二步&#xff1a;添加窗体 第三步&#xff1a;添加控件 第四步&#xff1a;双击控件&#xff0c;在控件点击方法内输入代码 第五步&#xff1a;在主程序内实例化新建的form类&#xff0c;并弹窗form窗体 第六步&#xff1a;CAD命…

1.2.3 TCP IP模型

TCP/IP模型&#xff08;接网叔用&#xff09; 网络接口层 网络层 传输层 应用层 理念&#xff1a;如果某些应用需要“数据格式转换”“会话管理功能”&#xff0c;就交给应用层的特定协议去实现 tip&#xff1a;数据 局部正确不等于全局正确 但是&#xff0c;数据的 全局正…

Codeforces Round 770 (Div. 2)

比赛链接&#xff1a;Dashboard - Codeforces Round 770 (Div. 2) - Codeforces A. Reverse and Concatenate 题意&#xff1a; 思路&#xff1a; 假设 s "abba" 经过1次操作后 -> "abbaabba" s "abcd" 经过一次操作后 -> "abcd…