linux中epoll模型

news/2024/7/9 15:49:27 标签: epoll

epoll是linux内核为处理大批量文件描述符而作了改进的poll,是linux下IO复用select/poll的增强版本。

一、epoll的主要接口是:

1、创建

(1)int epoll_create(int maxfds);

maxfds是支持的最大句柄数。该函数会返回一个新的epoll句柄,之后的函数调用都用这个句柄来操作。用完之后,记得用close()关闭这个创建出来的epoll句柄,否则可能导致系统fd被耗尽。

(2)int epoll_reate1(int flag);

上面创建的方法在linux 2.6.8之后,maxfds是被忽略的,所以建议采用epoll_create1(0)这种方法。另外epoll_create1(EPOLLCLOEXEC)表示生成的epoll fd具有“执行后关闭”的特性。

2、事件注册

int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);

epoll的事件注册函数,它不同于select/poll在监听的时候告诉内核要监听什么事件,而是先注册要监听的事件类型。

(1)epfd为(1)返回的epoll句柄

(2)op表示动作,用三个宏来表示:

EPOLL_CTL_ADD:注册新的fd到epfd中

EPOLL_CTL_MOD:修改已注册的fd的监听事件

EPOLL_CTL_DEL:从epfd中删除一个fd

(3)fd为要监听的fd

(4)event为要监听的事件,结构如下:

struct epoll_event

{

__uint32_t events;

epoll_data_t data;

};

events可以是一下宏的集合:

EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);

EPOLLOUT:表示对应的文件描述符可以写;

EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);

EPOLLERR:表示对应的文件描述符发生错误;

EPOLLHUP:表示对应的文件描述符被挂断;

EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。

EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里

3、等待事件发生

int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);

等待事件发生,类似于select()调用。参数events用来从内核得到事件的集合,maxevents告诉内核这个events有多大,maxevents不能大于epoll_create时设置的size,参数timeout是超时时间(毫秒,0立即返回,-1将永久阻塞)。该函数返回需要处理的事件数目,如果返回0表示已超时。

二、epoll的两种工作模式

epoll默认的工作模式是Level Triggered,通过epoll_ctl可以设置epoll的工作模式为Edge Triggered。

LT(levet triggered)同时支持block和no-block socket。在该模式下,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错的可能性要小一点。传统的select/poll都是这种模型的代表。

ET(edge triggered)是高速工作方式,只支持non-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。如果描述符没有再次发生IO操作(导致它再次变成未就绪),内核不会发送更多的通知。例如:ET模式下epoll_wait返回,当前缓存中接收到了2KB的数据,调用read读取1KB的数据。下次循环调用epoll_wai时将不会受到内核通知,将阻塞在这里,直到发生IO操作(如又收到数据)。当调用read或者write返回EAGAIN时,才需要挂起。但我们一般在处理循环读时,当read()返回的读到的数据长度小于请求的数据长度时,就可以确定此时缓冲中已没有数据了,也就可以认为此事读事件已处理完成。

三、epoll相对于select/poll的优势

1、epoll通过epoll_ctl注册监听的事件,而不像select/poll在每次循环调用select/poll函数时,设置监听事件,把fd集合从用户态拷贝到内核态),这个开销在fd很多时会很大。

2、select/poll在监听事件发生后,需要遍历所有fd,这个开销在fd很多时也很大,而epoll_wait返回的就是需要处理的事件。

3、select支持的最大文件描述符个数默认为1024,不适合处理大批量的文件描述符。而epoll就没有限制。

4、在并发连接数较大而活动连接数较小时,epoll比poll效率更高;而如果所有连接基本都是活跃的,比如一个高速LAN环境,epoll并不比select/poll有什么效率。

转载于:https://www.cnblogs.com/justkong/p/7196768.html


http://www.niftyadmin.cn/n/1090118.html

相关文章

Linux基础命令---间歇执行命令---watch

watch watch指令可以间歇性的执行程序&#xff0c;将输出结果以全屏的方式显示&#xff0c;默认是2s执行一次。watch将一直运行&#xff0c;直到被中断。 此命令的适用范围&#xff1a;RedHat、RHEL、Ubuntu、CentOS、SUSE、openSUSE、Fedora。 语法watch [-dhvt] [-n <se…

JBuilder2005实战JSP之日志和部署

用户登录和退出日志  当用户登录系统时&#xff0c;在日志表中插入一条记录&#xff0c;记录用户登录的时间&#xff0c;在用户退出系统时记录用户退出系统的时间。  我们利用HttpSessionBindingListener接口来完成记录登录和退出日志的功能&#xff0c;该接口中定义了两个…

echarts ajax数据加载方法总结(详细)

方法一&#xff1a; data为数组类型的&#xff0c;data:[10,20,30]; HTML <div class"d_main" id"main3"></div> css .d_main{width:80%;height:400px;margin:0 auto;} js 1 var myChart3 echarts.init(document.getElementById(main3));// …

Linux基础命令---显示登录用户w

w 显示哪些用户登录&#xff0c;并且显示用户在干什么。报头按此顺序显示当前时间、系统运行时间、当前登录用户数以及过去1、5和15分钟的系统平均负载。接着为每个用户显示以下条目&#xff1a;登录名、TTY名称、远程主机、登录时间、空闲时间、JCPU、PCPU和当前进程的命令行。…

在visual studio中设置点击左边选项卡中的类文件,右侧解决方案跳到对应的文件...

在visual studio中如何设置点击左边选项卡中的类文件,右侧解决方案跳到对应的文件&#xff1f;比如说&#xff0c;VS上方的选项卡文件较多&#xff0c;我点击选项卡上的任一文件&#xff0c;解决方案中对应的文件突出显示默认情况下&#xff0c;Visual Studio会在“解决方案资源…

Thrift官方安装手册(译)

本篇是Thrift官网安装文档的翻译&#xff0c;原地址点击这里。Thrift之前是不支持Windows的。但是似乎0.9版本以后已经支持Window了。介绍了Thrift安装的环境要求以及在centos,Debian/Ubuntu,OS X和Windows下的安装过程。并提出了一些安装过程中可能遇到的问题和解决办法。适用…

上周某一天

import datatime import calendar def get_last_sunday(time):"""datatime ->str返回上周的星期天"""oneday datetime.timedelta(days1)if time.weekday() calendar.SUNDAY:  #要星期几&#xff0c;就选星期几timetime-onedaywhile time.w…

自制代码生成器

在敲机房收费系统的时候&#xff0c;由于用三层的思想时须要用到实体类。最麻烦的是不断的来定义实体的属性值&#xff0c;真实烦人。想一想有没有好的方法来操作呢&#xff1f; 注意&#xff1a;实体的属性是与数据库中表的字段是相互相应的。从网上查资料发现了代码生成器这个…