linux文件IO:epoll

news/2024/12/15 16:40:29/文章来源:https://www.cnblogs.com/sgqmax/p/18608141

poll和select的改进版,在一个程序需要处理数百个文件描述符时很有用

2.6内核引入epoll机制,解决了poll和select的性能问题,并加入了一些新特性
poll和select每次调用都需要所有被监听的文件描述符,内核需要遍历所有的文件描述符,当数量变大时,性能消耗巨大

epoll将监听注册从实际监听中分离,从而解决了该问题
一个系统调用初始化一个epoll上下文,另一个从上下文中加入和删除文件描述符,第三个执行真正的事件等待

创建一个epoll实例

#include<sys/epoll.h>
int epoll_create(int size);

创建一个epoll实例,返回与该实例相关的文件描述符
size指定需要监听的文件描述符数量,传递一个近似值会带来性能提升

出错时返回-1,并设置errno
EINVAL size不是正数
ENFILE 系统达到打开文件数上限
ENOMEN 没有足够内存完成操作

int epfd= epoll_create(100);
if(epfd<0){perror("epoll create err");
}

文件描述符需要调用close关闭

控制epoll

#include<sys/epoll.h>
int epoll_ctl(int epfd, in op, int fd, struct epoll_event* event);

向指定的epoll上下文加入或删除文件描述符

struct epoll_event{__u32 events;union{void* ptr;int fd;__u32 u32;__u64 u64;}data;
};

参数op指定要对fd进行的操作
参数event指定更具体的行为

op取值如下

op字段 说明
EPOLL_CTL_ADD 添加fd到epfd指定的epoll实例中
EPOLL_CTL_MOD 使用event修改在已有fd上的监听行为
EPOLL_CTL_DEL 从epfd指定的epoll实例中删除fd

epoll_event结构体指定了在文件描述符上的监听事件
epoll_event.events字段取值如下,可用位或运算符同时设置

events字段 说明
EPOLLERR 文件出错,即使没有设置,该事件也是会被监听
EPOLLET 在监听文件上开启边沿触发
EPOLLHUP 文件被挂起,即使没有设置,该事件也是会被监听
EPOLLIN 文件未阻塞,可读
EPOLLONESHOT 在一次事件产生并被处理后,文件不再被监听
EPOLLOUT 文件未阻塞,可写
EPOLLPRI 高优先级的带外数据可读

epoll_event.data字段由用户使用,确认事件后会返回给用户
通常将epoll_event.data.fd设置为指定的fd,从而可以知道触发事件的文件描述符

返回值,成功返回0,失败返回-1,并设置errno为下列值

errno值 说明
EBADF epfd不是有效的epoll实例,或fd不是有效的文件描述符
EEXIST op为EPOLL_CTL_ADD,但fd已与epfd关联
EINVAL epfd不是一个epoll实例,epfd与fd相同,或op无效
ENOENT op为EPOLL_CTL_MOD和EPOLL_CTL_DEL,但fd没有与epfd关联
ENOMEN 没有足够内存完成进程请求
EPERM fd不支持epoll

在epfd实例中加入一个fd指定的监听文件

struct epoll_event evt;
evt.data.fd= fd;
evt.events= EPOLLIN | EPOLLOUT;
int ret= epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &evt);
if(ret){perror("epoll ctl");
}

修改epfd实例中的fd上的一个监听事件

struct epoll_event evt;
evt.data.fd= fd;
evt.events= EPOLLIN;
int ret= epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &evt);
if(ret){perror("epoll ctl");
}

op为EPOLL_CTL_DEL时,因为没有设置事件,event参数可以为NULL

等待epoll事件

#include<sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event* event, int maxevents, int timeout);

等待epfd实例中的fd上的事件,超时timeout毫秒
成功返回,events指向包含epoll_event结构体的内存,最多可以有maxevents个事件
返回值为事件数,出错返回-1,并设置errno为如下值

errno值 说明
EBADF epfd为无效文件描述符
EFAULT 进程对events指向的内存无写权限
EINTR 系统调用在完成前被信号中断
EINVAL epfd不是有效的epoll实例,和maxevents小于0

若timeout为0,即使没有事件发生,也会立即返回,此时调用返回0
若timeout为-1,将一直等待到有事件发生

一个完整的epoll_wait示例

#define MAX_EVENTS 64
int epfd;struct epoll_event* events;
events= malloc(sizeof(struct epoll_event)* MAX_EVENTS);
if(!events){perror("malloc")return 0;
}int nr_events= epoll_wait(epfd, events, MAX_EVENTS, -1);
if(nr_events<0){perror("epoll_wait");free(events);return 0;
}for(int i=0; i<nr_events; i++){printf("event=%ld on fd=%d\n", events[i].events, events[i].data.fd);
}
free(events);

边沿触发事件和水平触发事件

epoll_ctl参数event中的events设置为EPOLLET,fd上的监听为边沿触发,相反则为水平触发

如下生产者和消费者在通过unix管道通信的情况
1.生产者向管道写入1kb数据
2.消费者在管道上调用epoll_wait,等待管道出现数据,从而可读

对于水平触发的监听,步骤2对epoll_wait的调用会立即返回
对于边沿触发的监听,调用会等到步骤1发生后才会返回,即使管道已有数据可读,调用也会等到有数据写入才会返回

水平触发是默认行为,是大多数开发者期望的,也是poll和select的行为
边沿触发需要一个不同的方式来写程序,通常利用非阻塞IO,并需要仔细检查EAGAIN

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python3虚拟机和对象

2024年最推荐的python3版本为3.11 python虚拟机和对象 Python对象和虚拟机_v4.pdf Python虚拟机的原理 • 字节码生成 • 虚拟机运行 Python对象的实现 • 数据结构 • 类型系统 • 内存管理 Python虚拟机字节码和机器码有什么区别 字节码和机器码是计算机程序执行的两种不同形…

Buffer

Buffer(缓冲器)1. 概念 Buffer 是一个类似于数组的 对象 ,用于表示固定长度的字节序列 Buffer 本质是一段内存空间,专门用来处理 二进制数据 。2. 特点 1. Buffer 大小固定且无法调整 2. Buffer 性能较好,可以直接对计算机内存进行操作 3. 每个元素的大小为 1 字节(byte)…

夜莺监控V6版本如何升级到V7

升级目的 为了使用新版本的一些功能特性,故此进行升级。 注意事项 软件升级通常关键三个点:二进制替换 配置文件按照最新的格式调整 数据库表结构所以,在做升级之前,一定要先做好备份,备份的内容对应变更的内容,即:二进制、配置文件、数据库。 升级过程这里演示以二进制…

数据采集与融合综合实践

综合设计——多源异构数据采集与融合应用综合实践这个项目属于哪个课程 2024数据采集与融合技术实践组名 数据"融合炖" 异构 "大杂绘"队项目简介 项目名称:味谱魔法 项目logo: 项目介绍:智能购物菜谱助手是一款结合AI技术的智能化应用,旨在为用户提供…

交易系统:退款单模型设计详解

大家好,我是汤师爷~ 和退款单作为整个交易逆向系统的核心,支撑着售后管理环节。 售后域核心概念模型1、退款单 退款单是记录和跟踪退款处理过程的核心业务单据,包含以下关键信息:租户ID:标识所属商户或组织 退款单ID:退款单的唯一标识 原订单ID:关联的原始订单 业务类型…

DDPM论文解读

Denoising Diffusion Probabilistic Models论文解读DDPM(Denoising Diffusion Probabilistic Models) 论文研究背景扩散概率模型(Denoising Diffusion Probabilistic Models, 简称DDPM)是近年来生成建模领域的重要发展之一。 生成模型的目标是学习数据分布并能够从中采样,…

AtCoder Beginner Contest 384 Solution

AtCoder Beginner Contest 384 (A-E) 题解A - aaaadaa (abc384 A) 题目大意 给个长度为n的字符串,以及两个字母a和b,要求把字符串中不是a的字符全部都变成b。 解题思路 一个循环判断一下就行了。 代码 #include<bits/stdc++.h> using namespace std; int main() {int n…

vs编译cpp时设置排除项

cpp编译排除 一个c++文件不需要被编译但还保留在工程中(阅读),可使用ExcludedFromBuild,有两种方法实现:图形化操作 改vs的项目配置文件图形化操作 在vs的资源管理器选中文件 - 右键 - 属性 - 切到当前的编译配置项(debug/release),有个选项【从生成中排除】,选择为是…

纪念程云大侠

与程云兄的缘份,起始于Delphi大富翁论坛,因 “程云的一堆SQL”而结缘,在论坛发起的第二次(玉渊潭)和第三次(香山)大富翁聚会中逐渐相熟。自2002年5月3日那场坛友初聚起,加上中间各种小聚,至近年来的4年多共事时光,不经意间,二十余载岁月已悄然流逝,往昔匆匆,仿若弹…

css第三天案例练习

案例一:新闻详情 字体颜色:color 字体大小:font-size 段落开头空两行:font-indent:2em 水平居中:图片(出错点)/文字text-align:center 字体粗细:font-weight:400(取消加粗)案例二:css简介 超链接设置格式

DVR4 pg walkthrough Intermediate window

nmap ┌──(root㉿kali)-[~/lab] └─# nmap -p- -A -sS 192.168.219.179 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-15 04:22 UTC Stats: 0:00:22 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan SYN Stealth Scan Timing: About 34.76% d…

计算机网络课程笔记

计算机网络课程 该笔记于 2024年12月15日15:14:02 编写 常用命令以及简写完整命令 简写形式 解释configure terminal conf t 进入全局配置模式enable en enableexit ex 退出当前模式hostname host 重启设备interface int 进入接口配置模式shutdown shut 禁用接口no shutdown no…