I/O复用epoll

来源:互联网 发布:局域网ip冲突 软件 编辑:程序博客网 时间:2024/05/18 16:54

这篇文章从别的地方抄过来的,原地址:

http://blog.chinaunix.net/uid-23842323-id-2656592.html

epoll是Linux内核为处理大批量句柄而坐改进的poll,是Linux下多路复用IO接口select,/poll的增强版,它能显著减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。(这个和selectpoll的实现有关系,select/poll的实现依赖于遍历全部传递的文件描述符进行监测)

一 epoll的优点

支持一个进程打开大数目的socket描述符。

IO效率不随FD数目增加而线性下降。

内核微调。

二 epoll的使用

epoll的2种工作方式:LT和ET

LT水平触发,是缺省的工作方式,并且同时支持block和no-block,在这做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的文件描述符进行IO操作。如果你不做任何操作,内核会持续通知你的,所以,这种模式编程出错的概率低。传统的select/poll采用的都是这种模型。

ET边缘模式是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪转为就绪的时候,内核通过epoll告诉你,然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致一个EWOULDBLOCK错误),但是请注意,如果一直不对这个fd进行任何IO操作(从而导致它再次变成未就绪),内核不会再发送更多的通知。

ET/LT的详细区别 

http://www.ccvita.com/515.html

ET 只支持no-block套接字,当文件描述符就绪的时候只通知一次,LT 当文件就绪的时候,若一直处于就绪状态则一直通知

epoll相关函数一共三个:epoll_create,epoll_ctl和epoll_wait

1 int epoll_create(int size); 参数size告诉内核要监听的数目一共多少个。即该epoll句柄能够关联的fd个数。

返回值:>0成功,返回epoll句柄,==-1创建失败可以通过errno获得相关的错误码。

注意,epoll相当于一个fd,所以每次使用完后进行close,否则会导致fd被耗尽。

2 int epoll_ctl(int epfd, int op, int  fd, struct epoll_event * events)

参数epfd, epoll_create返回的值;

参数op:操作选项;

fd;要进行监测的目标文件描述符;

event::struct epoll_event结构指针,将fd和要进行的操作关联起来。

返回值:成功的时候返回0,失败返回-1;

参数op的可选项:

EPOLL_CTL_ADD :注册新的fd到epfd;

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

EPOLL_CTL_DEL:从epfd中删除fd

struct epoll_event的结构

typedef union epoll_data{

void *ptr;

int fd;

_uint32_t u32;

_uint3264_t u64;

} epoll_data_t;


struct epoll_events{

_uint32_t events;

epoll_data_t data;

};


events可以是以下几个宏的集合:

EPOLLIN表示对应的文件描述符可以读,对端的套接字关闭也可以进行读;

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

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

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

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

EPOLLET:将EPOLL设为ET;

EPOLLONESHOT:只监听一次事件,当监听的事件发生后,如果还要继续监听这个套接字,则需要再次把fd加入epfd队列中


int epoll_wait(int epfd, struct epoll_event *events,int maxevent, int tumeout)

参数epfd:epoll_create返回的epoll句柄

参数events:struct epoll_event结构指针,用来从内核得到事件的集合。

参数maxevents:告诉内核这个events有多大

参数timeout 等待超时的时间,单位毫秒。

返回值:成功的时候,返回要处理的事件数目,调用失败,-1,超时0


0 0