Linux之epoll理解
IO多路复用有几种实现方式:select poll和epoll。本篇文章对epoll进行总结理解。
IO多路复用的含义,我个人的理解是通过一个线程实现对多个socket的侦听,epoll与select和poll的区别是epoll效率最高。select的最高管理1024个socket并且是通过轮询的方式实现的管理,管理的socket个数越多,耗时越长。而epoll则没有1024这个限制,并且不是通过轮询的方式实现,这也是epoll应用于高并发的场景的原因所在。
epoll是一种IO事件通知机制。
select | poll | epoll | |
---|---|---|---|
性能 | 随着连接数的增加,性能急剧下降,处理成千上万的并发连接数时,性能很差 | 随着连接数的增加,性能急剧下降,处理成千上万的并发连接数时,性能很差 | 随着连接数的增加,性能基本没有变化 |
连接数 | 一般1024 | 无限制 | 无限制 |
内存拷贝 | 每次调用select拷贝 | 每次调用poll拷贝 | fd首次调用epoll_ctl拷贝,每次调用epoll_wait不拷贝 |
数据结构 | bitmap | 数组 | 红黑树 |
内在处理机制 | 线性轮询 | 线性轮询 | FD挂在红黑树,通过事件回调callback |
时间复杂度 | O(n) | O(n) | O(log(n)) |
epoll是IO多路复用的一种实现方式,也是目前主流的高并发实现方案。
epoll的作用
经常看到epoll的作用,也知道他是IO多路复用的一种实现形式,但是由于过往经历使用select比较多,对epoll总是知其然,而不知其所以然。
epoll主要用于对socket进行侦听,实现一个线程对多个socket的管理,相对于select和poll能够有效的减少系统开销,性能稳定。
epoll的API接口
int epoll_create(int size);
功能:该函数生成一个 epoll 专用的文件描述符。
参数size: 用来告诉内核这个监听的数目一共有多大,参数 size 并不是限制了 epoll 所能监听的描述符最大个数,只是对内核初始分配内部数据结构的一个建议。自从 linux 2.6.8 之后,size 参数是被忽略的,也就是说可以填只有大于 0 的任意值。返回值:如果成功,返回poll 专用的文件描述符,否者失败,返回-1。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:epoll 的事件注册函数,它不同于 select() 是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。参数epfd: epoll 专用的文件描述符,epoll_create()的返回值参数op: 表示动作,用三个宏来表示:
EPOLL_CTL_ADD:注册新的 fd 到 epfd 中;
EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
EPOLL_CTL_DEL:从 epfd 中删除一个 fd;
参数fd: 需要监听的文件描述符参数event: 告诉内核要监听什么事件,struct epoll_event 结构如:events 可以是以下几个宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端 SOCKET 正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET :将 EPOLL 设为边缘触发(Edge Trigger)模式,这是相对于水平触发(Level Trigger)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个 socket 的话,需要再次把这个 socket 加入到 EPOLL 队列里返回值:0表示成功,-1表示失败。
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
功能:等待事件的产生,收集在 epoll 监控的事件中已经发送的事件,类似于 select() 调用。参数epfd: epoll 专用的文件描述符,epoll_create()的返回值参数events: 分配好的 epoll_event 结构体数组,epoll 将会把发生的事件赋值到events 数组中(events 不可以是空指针,内核只负责把数据复制到这个 events 数组中,不会去帮助我们在用户态中分配内存)。参数maxevents: maxevents 告之内核这个 events 有多少个 。参数timeout: 超时时间,单位为毫秒,为 -1 时,函数为阻塞。返回值:如果成功,表示返回需要处理的事件数目
如果返回0,表示已超时
如果返回-1,表示失败
epoll为什么高效?
说到epoll为什么高效,还是要从IO多路复现的实现历史说起,IO多路复用的实现最初是select,然后select有几个问题:
- 默认的select实现管理的socket数量一般为1024,数量存在限制,虽然可以修改,但是需要重新编译内核
- 每次调用select接口,都会将侦听的fd的数组从用户态内存拷贝到内核态缓冲区;另外当有socket可读或者可写时也会将fd数组从内核态缓冲区拷贝至用户态内存。用户态至内核态或者内核态至用户态数据的拷贝,这样的拷贝对于资源的消耗是很大的。
- 无论是内核态还是用户态由于保存fd的是一个数组,都需要通过轮询的方式遍历fd数组,找到可读或者可写的fd,当fd数量增大时,性能是下降的。
select运行原理示意视频:
select-CSDN直播
针对select存在这样的问题,后续发展出了poll,但是poll相对于select的优化有限,仅仅只改善了select管理socket上线的问题,其余两点都没有进行优化。
再往后就发展了出了epoll,epoll相对于select和poll出现了跨越式的改进,将select涉及的问题都做了响应的改进:
- 管理的socket无上限,而且是通过函数传参的形式指定管理的socket个数,而select是通过头文件中的FD_SIZE来指定的。不言而喻,通过函数传参的方式更灵活。
- epoll内部管理fd的数据结构是红黑树,查找、修改和删除的时间复杂度都很优秀。
- epoll_wait的每次调用不会向select调用一样,每次都会产生用户态到内核态的拷贝,从而减少资源消耗
- 当内核检测到某个fd的可读或者可写事件时,会自动调用该fd的poll回调函数,将该fd的信息拷贝到数组中
- epoll仅会将检测到可读可写的事件fd写入到数组中,传递到用户态内存中,这一点与select是不同的,select是要所有监听的fd的集合拷贝到用户区中。
总结起来就是:
- 管理的socket无上限
- 用户态内存和内核缓冲区内存拷贝次数减少
- 传递出的可读或者可写的事件仅包含这些可读可写的fd,这一点也是与select不同的,select传出的是所有fd的集合。
epoll运行原理示意视频:
epoll-CSDN直播
epoll的触发方式
epoll有两种触发方式,一种是水平触发,一种是边缘触发。
- 水平触发,这种触发方式的含义是只要读缓冲区存在数据,epoll会一直提示该fd有可读事件;当为写缓冲区时,如果写缓冲区空间不满,则epoll_wait会提示用户该fd有可写事件。epoll默认的触发方式是水平触发。
对于读操作,只要缓冲内容不为空,LT模式返回读就绪。
对于写操作,只要缓冲区还不满,LT模式会返回写就绪。
当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在尚没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你。如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率。
- 边缘触发,只有当缓冲区的状态发生变化的时候才会触发可读可写事件。例如读缓冲区内由无数据变为有数据,只有此种情况下才会触发可读事件,也就是说对于读缓冲区,读缓冲区从数据变为有数据,只会发送一次可读事件,至于读缓冲区内的事件是否读完不太关心,需要用户自己去处理;若为写缓冲区,写缓冲区由不可写入变为可以写入的情况下会触发可写事件,其余情况不会触发该事件。若要修改边沿触发模式,则需要调用epoll_ctl接口修改,在event参数中添加EPOLLET即可。
对于读操作
当缓冲区由不可读变为可读的时候,即缓冲区由空变为不空的时候。
当有新数据到达时,即缓冲区中的待读数据变多的时候。
当缓冲区有数据可读,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLIN事件时。
对于写操作
当缓冲区由不可写变为可写时。
当有旧数据被发送走,即缓冲区中的内容变少的时候。
当缓冲区有空间可写,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLOUT事件时。
当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你。这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符。
在ET模式下, 缓冲区从不可读变成可读,会唤醒应用进程,缓冲区数据变少的情况,则不会再唤醒应用进程。
对于水平触发和边缘触发更形象的解释:
水平触发:0为无数据,1为有数据。缓冲区有数据则一直为1,则一直触发。
边缘触发发:0为无数据,1为有数据,只要在0变到1的上升沿才触发。
JDK并没有实现边缘触发,Netty重新实现了epoll机制,采用边缘触发方式;另外像Nginx也采用边缘触发。
JDK在Linux已经默认使用epoll方式,但是JDK的epoll采用的是水平触发,而Netty重新实现了epoll机制,采用边缘触发方式,netty epoll transport 暴露了更多的nio没有的配置参数,如 TCP_CORK, SO_REUSEADDR等等;另外像Nginx也采用边缘触发。
epoll与设计模式的关系
待补充
参考链接
epoll详解
不同的IO多路复用具体实现
相关文章:
Linux之epoll理解
IO多路复用有几种实现方式:select poll和epoll。本篇文章对epoll进行总结理解。 IO多路复用的含义,我个人的理解是通过一个线程实现对多个socket的侦听,epoll与select和poll的区别是epoll效率最高。select的最高管理1024个socket并且是通过轮…...
龟速乘 - a * b爆ll且模数很大时的计算方法
LL qmul(LL a, LL k, LL b) {LL res 0;while (k){if (k & 1) res (res a) % b;a (a a) % b;k >> 1;}return res; } 如果int128也会爆掉的话可以用这种方法 也是快速幂的思想,快速幂是乘,这个是加...

计算机网络笔记3 数据链路层
计算机网络系列笔记目录👇 计算机网络笔记6 应用层计算机网络笔记5 运输层计算机网络笔记4 网络层计算机网络笔记3 数据链路层计算机网络笔记2 物理层计算机网络笔记1 概述 文章前言 💗 站在巨人的肩膀上,让知识的获得更加容易!…...
如何实现矩阵的重采样问题
文章目录 前言一、问题描述二、回答 前言 记录知乎的自问自答。 一、问题描述 我的问题是这样的,有两个列向量E和F,需要注意的是,E和F是连续的,可任意插值,得到包含其中的子向量。E和F通过一个mn的矩阵联系起来&…...

Spring-事务管理-加强
目录 开启事务 编程式事务 声明式事务 声明式事务的优点 声明式事务的粒度问题 声明式事务用不对容易失效 Spring事务失效可能是哪些原因 Transactional(rollbackFor Exception.class)注解 Spring 事务的实现原理 事务传播机制 介绍 用法 rollbackFor 场景举例 …...

Minecraft个人服务器搭建自己的皮肤站并实现外置登录更换自定义皮肤组件
Minecraft个人服务器搭建自己的皮肤站并实现外置登录更换自定义皮肤组件 大家好,我是艾西有不少小伙伴非常喜欢我的世界Minecraft游戏,今天小编跟大家分享下Minecraft个人服务器怎么设置皮肤站。 Minecraft皮肤站是什么?其实官网就有皮肤站…...

解决ubuntu中没有网络连接的图标
现象:Ubuntu连接网络 在设置中没有显示网络图标 解决方案: 命令为 sudo nmcli networking off sudo nmcli networking on sudo service network-manager restart 重启ubuntu,网络连接完成...

数据结构基本概念-Java常用算法
数据结构基本概念-Java常用算法 1、数据结构基本概念2、数据逻辑结构3、算法时间复杂度 1、数据结构基本概念 数据(Data):数据是信息的载体,其能够被计算机识别、存储和加工处理,是计算机程序加工的“原材料”。数据元…...

流程图设计制作都有哪些好用的工具
流程图是一种直观的图形表示方式,通常用于显示事物的过程、步骤和关系。在现代工作中,设计师经常需要绘制各种流程图来解释工作过程、产品设计等。本文将为您推荐7个流程图软件,以帮助您快速绘制高效的流程图,并提高工作效率。 即…...
2023-10-7
今日感冒了,整个人都不舒服,现在才 8 点,已经不想学习了。嗓子眼感觉不属于我了,痛死了。然后头也晕。 哎,今天又啥也没干 今日学习: 哎,今天就做了 RWCTF2022-Digging-into-kernel-2 这道题…...

【java源码】二甲医院his系统全套源码 云HIS系统源码
基层医院云HIS系统源码 一款满足基层医院各类业务需要的云HIS系统。该系统能帮助基层医院完成日常各类业务,提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能,还能与公卫、PACS等各类外部系统融合&…...
LRU 缓存 -- 哈希链表
相关题目 146. LRU 缓存 要让 put 和 get ⽅法的时间复杂度为 O(1),我们可以总结出 cache 这个数据结构必要的条件: 1、显然 cache 中的元素必须有时序,以区分最近使⽤的和久未使⽤的数据,当容量满了之后要删除最久未使⽤的那个元…...

DWC数字世界大会先导论坛将于10月13日在宁波举办 | 数字技术赋能世界可持续发展
农业经济影响世界数千年,工业经济从欧美发源开始已有数百年,数字经济作为世界未来发展之大势,将成为影响未来数百年的世界命题。在以中国式现代化全面推进中华民族伟大复兴的历史征程中,数字技术、数字经济作为中国式现代化实践最…...

Springboot实现登录功能(token、redis、登录拦截器、全局异常处理)
登录流程: 1、前端调用登录接口,往接口里传入账号,密码 2、根据账号判断是否有这个用户,如果有则继续判断密码是否正确 3、验证成功后,则是根据账号,登录时间生成token(用JWT) 4、将…...

AI工程化—— 如何让AI在企业多快好省的落地?
文章目录 前言内容简介读者对象专家推荐目录赠书活动 前言 作为计算机科学的一个重要领域,机器学习也是目前人工智能领域非常活跃的分支之一。机器学习通过分析海量数据、总结规律,帮助人们解决众多实际问题。随着机器学习技术的发展,越来越多…...
mysqld_multi测试
mysqld_multi测试 mysql版本:5.7.25-log 在OS上分别安装了两套mysql, data目录为/mysql/mysql3306、 /mysql/mysql3307 。 端口分别为3306 、3307 配置文件为: /mysql/mysql3306/my.cnf /mysql/mysql3307/my.cnf 参考文档: htt…...
MDC方式实现简单链路追踪
MDC 方式实现日志链路追踪 拦截器 package com.cdn.log.interceptor;import com.cdn.log.consts.CLogConst; import com.cdn.log.utils.IdUtil; import org.slf4j.MDC; import org.springframework.util.StringUtils; import org.springframework.web.servlet.ModelAndView; im…...

Linux深度学习:除基本命令操作外的实用操作
Linux深度学习:除基本命令操作外的实用操作 软件安装systemctl软连接日期、时区IP地址、主机名网络传输下载和网络请求端口 进程管理主机状态系统资源监控磁盘信息监控网络状态监控 环境变量上传、下载压缩、解压root用户、用户、用户组管理查看、修改权限控制 软件…...

app对接广告变现平台:影响app广告单价的4大因素
在移动应用开发者和媒体公司竞相寻求提高广告变现效率的今天,理解影响APP广告单价的关键因素至关重要。广告单价是广告收入的核心组成部分,它受多种因素的影响,直接关系到媒体的盈利能力。主要因素大概有以下几点:#APP广告变现# …...

【数字化转型】10大数字化转型能力成熟度模型01(IOMM)
一、前言 数字化转型是数据化能力建设的目标和价值,作为一个新兴的课题,目前为止并未出现一个统一的数字化转型成熟度模型。不同的企业和机构,根据自身的发展和认知,推出了自己的企业级或者准行业级标准。这些标准具有很强的参考意…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...