在Linux上,执行man epoll之后,可以得到这些结果
- NAME
- epoll - I/O event notification facility
- SYNOPSIS
- #include <sys/epoll.h>
- DESCRIPTION
- epoll is a variant of poll(2) that can be used either as Edge or Level Trig-
- gered interface and scales well to large numbers of watched fds. Three system
- calls are provided to set up and control an epoll set: epoll_create(2),
- epoll_ctl(2), epoll_wait(2).
- An epoll set is connected to a file descriptor created by epoll_create(2).
- Interest for certain file descriptors is then registered via epoll_ctl(2).
- Finally, the actual wait is started by epoll_wait(2).
epoll相关的的系统调用有:epoll_create, epoll_ctl和epoll_wait。
epoll_create用来创建一个epoll文件描述符。
epoll_ctl用来添加、修改、删除需要侦听的文件描述符及其事件。
epoll_wait/epoll_pwait 接收发生在被侦听的描述符上的,用户感兴趣的IO事件。
这个条件符使用完之后,直接用close关闭即可。另外,任何被侦听的文件描述拊只要其被关闭,那么它也会自动的从被侦听的文件描述符集体中删除。
一,epoll_create
函数声明如下: int epoll_create(int maxfds)
参数表示EPOLL所支持的最大句柄数,函数会返回一个新的EPOLL句柄,之后的所有操作将通过这个句柄来进行操作。该 函数生成一个epoll专用的文件描述符,会向内核申请一空间,用来存放你想存眷的socket fd上是否产生以及产生了什么事务。
二,epoll_wait
函数声明如下:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)。
这个函数在网络的主循环里面调用,每一次调用都会查询所有的网络接口,查看哪一个可以读取,哪一个可以写数据了。一般这个函数返回之后,后面都是一个循环体,用于处理所有返回的可以读写的网络设备,如
- for(i=0;i<nfds;i++){
- if(event[n].data.fd == listenXXfd){
- accept(...);
- }
- }
epfd : 是epoll_create 创建返回的句柄。
events:存储所有的读写事件。常用的事件类型有:
- EPOLLIN :默示对应的文件描述符可以读;
- EPOLLOUT:默示对应的文件描述符可以写;
- EPOLLPRI:默示对应的文件描述符有紧急的数据可读
- EPOLLERR:默示对应的文件描述符产生错误;
- EPOLLHUP:默示对应的文件描述符被挂断;
- EPOLLET:默示对应的文件描述符有事务产生;
maxevents : 每次最多处理的事件数。
timeout:表示epoll_wait的超时,如果设为0,表示马上返回,-1的时候,会一直等下去,直到有事件发生。
在使用的时候,如:
- struct epoll_event ev;
- ev.data.fd= 网络文件描述符;
- ev.events=EPOLLIN|EPOLLET;
- typedef union epoll_data {
- void *ptr;
- int fd;
- __uint32_t u32;
- __uint64_t u64;
- } epoll_data_t;
- struct epoll_event {
- __uint32_t events; /* Epoll events */
- epoll_data_t data; /* User data variable */
- };
epoll_wait在调用时,要注意其原理是:等侍注册在epfd上的socket fd的事务的产生,若是产生则将产生的sokct fd和事务类型放入到events数组中。并且将注册在epfd上的socket fd的事务类型给清空,所以若是以后还要用这个socket fd的话,则须要用epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev)来从头设置socket fd的事务类型。但socket fd并未清空,这一步很是首要。
三,epoll_ctl
这个函数添加,修改或删除被侦听文件描述符,一般这个操作不要频繁的调用,太多的调用,可能会成为系统性能的杀手。
函数声明如下:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
epfd:由 epoll_create 生成的epoll专用的文件描述符;
op:要进行的操纵例如注册事务,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除
fd:接入关系的socket文件描述符;
event:指向epoll_event的指针;
若是调用成功返回0,不成功返回-1
四,epoll的操作是很简单的,一共就几个API。调用也很简单。
![linux](https://i-blog.csdnimg.cn/blog_migrate/23f987522c5046c33c7069971df59c81.gif)