Linux 中 epoll 的详解
Linux 中 epoll 的详解
epoll 是 Linux 内核提供的一种高效的 I/O 多路复用机制,用于监控大量文件描述符的 I/O 事件。相较于传统的 select 和 poll,epoll 在高并发和大规模网络编程场景下表现出色,特别适合需要处理成千上万个文件描述符的应用。
1. epoll 的特点
优点
-
高效性:
- 内核采用事件驱动机制,只在有事件时通知程序,而不是轮询所有文件描述符。
- 避免了重复构造文件描述符集合的开销。
-
无文件描述符上限:
- 文件描述符数量仅受系统资源限制,而不像
select的FD_SETSIZE限制(默认 1024)。
- 文件描述符数量仅受系统资源限制,而不像
-
支持边缘触发(ET)和水平触发(LT):
- ET:仅在状态变化时触发通知。
- LT:只要状态未清除,就会持续触发通知。
-
内存拷贝优化:
- 用户态和内核态之间的交互效率更高。
缺点
- 仅支持 Linux 系统,跨平台性较差。
- 边缘触发(ET)模式需要额外的逻辑处理,编程复杂度较高。
2. epoll 的使用方法
epoll 的使用主要分为三步:
1. 创建 epoll 实例
使用 epoll_create1 或 epoll_create 创建一个 epoll 实例:
#include <sys/epoll.h>int epoll_create1(int flags);
int epoll_create(int size);
flags:设置为 0 或EPOLL_CLOEXEC(子进程不继承)。- 返回值:一个文件描述符,用于管理
epoll实例。
2. 注册和管理文件描述符
使用 epoll_ctl 添加、修改或删除监控的文件描述符:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd:epoll_create返回的文件描述符。op:操作类型(EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL)。fd:需要监控的文件描述符。event:事件结构体,定义了监控的事件类型和用户数据。
struct epoll_event {uint32_t events; /* 事件类型 */epoll_data_t data; /* 用户数据 */
};typedef union epoll_data {void *ptr;int fd;uint32_t u32;uint64_t u64;
} epoll_data_t;
events常见值:EPOLLIN:可读事件。EPOLLOUT:可写事件。EPOLLERR:错误事件。EPOLLET:边缘触发模式。EPOLLHUP:挂起事件。
3. 等待事件发生
使用 epoll_wait 阻塞等待事件:
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
epfd:epoll_create返回的文件描述符。events:用于存储触发的事件。maxevents:events数组的最大长度。timeout:超时时间(毫秒)。0:立即返回。-1:无限等待。
返回值:发生事件的文件描述符数量。
3. epoll 使用示例
示例:基本用法
以下代码展示如何使用 epoll 同时监控标准输入和一个文件描述符:
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>int main() {int epfd = epoll_create1(0); // 创建 epoll 实例if (epfd == -1) {perror("epoll_create1");exit(EXIT_FAILURE);}struct epoll_event ev, events[10];ev.events = EPOLLIN; // 监控可读事件ev.data.fd = STDIN_FILENO; // 标准输入if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1) {perror("epoll_ctl");exit(EXIT_FAILURE);}printf("等待输入...\n");while (1) {int nfds = epoll_wait(epfd, events, 10, -1); // 无限等待if (nfds == -1) {perror("epoll_wait");exit(EXIT_FAILURE);}for (int i = 0; i < nfds; ++i) {if (events[i].data.fd == STDIN_FILENO) {char buffer[1024];int len = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);if (len > 0) {buffer[len] = '\0';printf("输入内容:%s\n", buffer);}}}}close(epfd);return 0;
}
4. epoll 的触发模式
水平触发(LT:Level Triggered)
- 默认模式。
- 如果文件描述符状态未清除,每次调用
epoll_wait都会触发事件。 - 容易实现,但性能稍低。
示例:
while (1) {int nfds = epoll_wait(epfd, events, 10, -1);for (int i = 0; i < nfds; ++i) {if (events[i].events & EPOLLIN) {read(fd, buffer, sizeof(buffer)); // 处理事件}}
}
边缘触发(ET:Edge Triggered)
- 高性能模式。
- 文件描述符状态发生变化时仅触发一次,必须读取或写入所有数据。
- 如果未处理完毕,可能会丢失事件。
实现注意:
- 必须使用非阻塞文件描述符。
- 需要循环读取或写入直到完成。
示例:
while (1) {int nfds = epoll_wait(epfd, events, 10, -1);for (int i = 0; i < nfds; ++i) {if (events[i].events & EPOLLIN) {while (1) {int len = read(fd, buffer, sizeof(buffer));if (len == -1) {if (errno == EAGAIN) break; // 无更多数据perror("read");} else if (len == 0) {break; // EOF} else {// 处理数据}}}}
}
5. epoll 的优缺点总结
优点
- 高性能:
- 基于事件通知机制,不需要线性扫描文件描述符集合。
- 灵活性:
- 支持边缘触发(ET)模式,减少不必要的系统调用。
- 无文件描述符限制:
- 能处理大量并发连接,适用于高并发服务器。
缺点
- 复杂性高:
- 编程复杂,特别是边缘触发模式需要处理更多细节。
- 仅适用于 Linux:
- 不支持其他平台,跨平台性较差。
6. epoll 应用场景
- 高并发服务器:
- 如 HTTP 服务器、代理服务器。
- 实时系统:
- 需要快速响应大量 I/O 事件。
- 高性能应用:
- 网络爬虫、流媒体服务器等。
相关文章:
Linux 中 epoll 的详解
Linux 中 epoll 的详解 epoll 是 Linux 内核提供的一种高效的 I/O 多路复用机制,用于监控大量文件描述符的 I/O 事件。相较于传统的 select 和 poll,epoll 在高并发和大规模网络编程场景下表现出色,特别适合需要处理成千上万个文件描述符的应…...
增加nginx配置文件(conf.d), 管理多个项目
1.切换到nginx目录下, 新建conf.d文件夹 mkdir conf.d 2.赋予conf.d权限 chmod 777 conf.d 3.进入conf.d, 编辑conf文件 vim zc_travel.conf server { listen 13101; server_name localhost;location / {root /home/baoxin/app/web/insight-radar-rcfx-pre/html_dev;index …...
PostgreSQL编译安装教程
下载安装 1.在家目录创建一个文件夹放下载安装包 mkdir softwarecd software 2.下载文件压缩包 wget https://ftp.postgresql.org/pub/source/v16.0/postgresql-16.0.tar.gz 3.解压 tar -xzvf postgresql-16.0.tar.gz 4.编译 在software/postgresql-16.0下 cd software…...
【提审】Android包提审报权限问题
问题:华为应用市场审核不通过 平台审核检测详情: 日志: 自检工具:frida-server【Unity&Android】安卓app自测应用隐私相关获取和申请权限_apk 隐私合规 自测-CSDN博客 参考资料:Unity启动时获取了android_id等设…...
xdoj 数字个数统计
1-2 数字个数统计 2 时间限制: 1S 题目描述: 一个正整数 n(1<n<1000),在区间[n,n2 ](含端点)内统计奇数个数、 偶数个数、能被 4 整除且不能被 3 整除的数字个数,并求出各统计数字两两…...
空天地遥感数据识别与计算--数据分析如何助力农林牧渔、城市发展、地质灾害监测等行业革新
在科技飞速发展的时代,遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究,空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而,对于许多专业人士而言,如何高效地处…...
Git:查看分支、创建分支、合并分支
一、查看分支 查看的git命令如下: git branch # 列出本地已经存在的分支,并且当前分支会用*标记 git branch -r # 查看远程版本库的分支列表 git branch -a # 查看所有分支列表(包括本地和远程,remotes/开头的表示远程分支&…...
联合目标检测与图像分类提升数据不平衡场景下的准确率
联合目标检测与图像分类提升数据不平衡场景下的准确率 在一些数据不平衡的场景下,使用单一的目标检测模型很难达到99%的准确率。为了优化这一问题,适当将其拆解为目标检测模型和图像分类模型的组合,可以更有效地控制最终效果,尤其…...
Git的简介
文章目录 一.Git是什么二.核心概念三.工作流程四.Git的优势 下载Git 推荐官网下载 官网地址 一.Git是什么 Git是一个分布式版本控制系统,用于跟踪文件的变化并协调多人对同一项目的开发工作。它就像是一个时光机器,能够记录文件在不同时间点的状态&…...
麒麟操作系统服务架构保姆级教程(四)NGINX中间件
如果你想拥有你从未拥有过的东西,那么你必须去做你从未做过的事情 想要在网页上访问到代码那么就需要用到应用服务类中间件,国外的有Nginx,Tomcat等,国内的有金蝶web,东方通的服务中间件(Tongweb࿰…...
Glide 自定义圆角、铺满FitXY
在 Android 开发中,使用 Glide 来加载图片时,有时需要对图片进行特定的处理,比如设置圆角或者使图片完全填充到一个视图中(类似于 ImageView 的 scaleType 中的 FitXY)。以下是如何使用 Glide 来实现这些自定义需求的处…...
蓝牙协议——音乐启停控制
手机播放音乐 手机暂停音乐 耳机播放音乐 耳机暂停音乐...
Krita安装krita-ai-diffusion工具搭建comfyui报错没有ComfyUI_IPAdapter_plus解决办法
我们在使用Kirta安装krita-ai-diffusion工具之后搭建comfyui环境需要安装很多扩展文件。 一般正常安装都可以使用了。 但是有一个插件很特别,无论你安装多少遍都会显示缺失,是什么插件这么难搞定呢? 没错,就是我们的ComfyUI_IPAdapter_plus插件。 就像下图一样: 那么怎…...
四相机设计实现全向视觉感知的开源空中机器人无人机
开源空中机器人 基于深度学习的OmniNxt全向视觉算法OAK-4p-New 全景硬件同步相机 机器人的纯视觉避障定位建图一直是个难题: 系统实现复杂 纯视觉稳定性不高 很难选到实用的视觉传感器 为此多数厂家还是采用激光雷达的定位方案。 OAK-4p-New 为了弥合这一差距…...
LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)
一、引言 1.1 医疗数据挖掘的重要性与挑战 在当今数字化医疗时代,医疗数据呈爆炸式增长,这些数据蕴含着丰富的信息,对医疗决策具有极为重要的意义。通过对医疗数据的深入挖掘,可以发现潜在的疾病模式、治疗效果关联以及患者的健康风险因素,从而为精准医疗、个性化治疗方…...
JVM(Java虚拟机)的组成部分详解
摘要: JVM (Java Virtual Machine) 是一个抽象计算模型,它使Java程序可以在任何支持JVM的操作系统上运行,而无需考虑底层硬件架构。本文将深入探讨JVM的内部结构和工作机制,包括类加载器、运行时数据区、执行引擎以及内存管理等关…...
jsp中的四个域对象(Spring MVC)
在Spring MVC中,Model中的数据会被自动放入到请求域(Request Scope)中。也就是说,当我们在控制器中使用model.addAttribute()时,这些属性会被放入到HttpServletRequest对象的属性中。 让我们通过代码来详细解释&#…...
计算机基础知识复习12.24
http和https有那些区别 http是超文本传输协议,信息是明文传输,存在安全风险的问题,https则解决http不安全的缺点,在TCP和HTTP网络层之间加入了SSL/TLS安全协议,使得报文能够加密传输 http连接建立相对简单࿰…...
如何使用vscode解决git冲突
在使用VSCode时,遇到Git冲突是很常见的情况。Git冲突是指当多个人同时修改同一个文件的同一行或相邻行时,Git无法自动决定应该保留哪一个修改,需要手动解决这个冲突。 要解决Git冲突,可以按照以下步骤操作: 1. 打开V…...
告别卡顿:CasaOS轻NAS设备安装Gopeed打造高效下载环境
文章目录 前言1. 更新应用中心2.Gopeed安装与配置3. 本地下载测试4. 安装内网穿透工具5. 配置公网地址6. 配置固定公网地址 前言 无论你是需要大量文件传输的专业人士,还是只是想快速下载电影或音乐的普通用户,都会使用到下载工具。如果你对现有的下载工…...
德州农机大学联合多所高校:AI从几张无序照片“脑补“出完整3D模型
这项由德州农机大学(Texas A&M University)联合澳门科技大学、西安电子科技大学、上海科技大学、香港科技大学、加州大学欧文分校等多所知名学府共同完成的研究发表于2026年4月的《ACM计算机图形学汇刊》(ACM Transactions on Graphics)第1卷第1期。这个名为UniRecGen的突破…...
Gradle国内镜像配置避坑指南:2024年最新阿里云源设置详解
Gradle国内镜像配置实战:2024年阿里云源深度优化方案 每次打开IDE看着进度条龟速前进,作为开发者的你是否也经历过这种绝望?特别是在紧急修复线上bug时,Gradle依赖下载的转圈动画简直能让人血压飙升。别担心,这份指南将…...
SamloaderKotlin 完全指南:跨平台三星固件下载工具的免费终极解决方案
SamloaderKotlin 完全指南:跨平台三星固件下载工具的免费终极解决方案 【免费下载链接】SamloaderKotlin 项目地址: https://gitcode.com/gh_mirrors/sa/SamloaderKotlin 你是否曾经为了下载三星官方固件而四处寻找工具?是否厌倦了那些复杂的命令…...
从认证到实现:功能安全与Class B在工业驱动中的核心实践
1. 工业驱动设备为什么需要功能安全认证 第一次接触功能安全认证时,我也觉得这不过是又一张"纸面证书"。直到亲眼见过电机失控把金属板材甩出十几米远,才真正理解为什么变频器和伺服驱动器必须通过功能安全认证。现在随便打开一台主流品牌的工…...
AcousticSense AI实战应用:短视频创作者BGM流派匹配提升完播率21%
AcousticSense AI实战应用:短视频创作者BGM流派匹配提升完播率21% 1. 引言:音乐匹配如何影响短视频完播率 短视频创作者都知道一个秘密:背景音乐的选择直接影响观众是否愿意看完整个视频。一段不合适的BGM可能会让观众在几秒钟内划走&#…...
IM系统核心不是聊天?深入剖析SpringBoot+Netty项目中关系链与群组模块的设计陷阱
IM系统核心不是聊天?深入剖析SpringBootNetty项目中关系链与群组模块的设计陷阱 当大多数人谈论即时通讯系统时,首先想到的是消息收发功能。然而,真正让微信、QQ等产品形成护城河的,并非简单的消息传输能力,而是其背后…...
数据库编程实战:从递归查询到异构数据迁移的完整解决方案
1. 递归查询实战:破解课程依赖关系网 第一次接触WITH RECURSIVE语法时,我正为在线教育平台设计课程推荐系统。平台里有门《机器学习入门》课程,竟然要求先修5门不同领域的基础课,而这些基础课本身又存在复杂的先修关系。传统JOIN查…...
智元GO-2:具身基座大模型新突破
智元机器人正式推出新一代具身基座大模型Genie Operator-2(GO-2),它在GO-1基础上进化,弥合语义‑运动鸿沟,在多个基准测试中刷新行业SOTA。进化亮点:弥合语义‑运动鸿沟GO-2在GO-1基础上进化,致…...
RePKG:深度解析Wallpaper Engine资源提取与纹理转换的终极方案
RePKG:深度解析Wallpaper Engine资源提取与纹理转换的终极方案 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 在Wallpaper Engine生态系统中,PKG文件提取和…...
KeymouseGo架构深度解析:跨平台自动化操作引擎的设计与实现
KeymouseGo架构深度解析:跨平台自动化操作引擎的设计与实现 【免费下载链接】KeymouseGo 类似按键精灵的鼠标键盘录制和自动化操作 模拟点击和键入 | automate mouse clicks and keyboard input 项目地址: https://gitcode.com/gh_mirrors/ke/KeymouseGo Key…...
